2017-07-21 5 views
0

Ich arbeite an einer Funktion, wo ich ein 3-Byte-Array konvertieren und das 3-Byte-Array als einzelnes int32 zurückgeben muss. Der Code ist wie folgt: pbData ist ein Zeiger auf das Byte-Array.Setzen des höchstwertigen Vorzeichen-Bits (Lint-Warnung)

const byte bMSBitPosNeg = 0x80; 
const byte bMSBNeg = 0xFF; 
int32 i32Num = 0; 

//Big - Endian 
if (pbData != NULL) 
{ 
    if ((pbData[0] & bMSBitPosNeg) == bMSBitPosNeg) //Negative 
    { 
     i32Num |= (bMSBNeg * 0x1000000); //Force MSB to 0xFF as 3 bytes are 
             //converted to 4 bytes 
    } 

    i32Num |= (pbData[0] << 16); 
    i32Num |= (pbData[1] << 8); 
    i32Num |= (pbData[2]); 

} 
return i32Num; 

Input: {0x00,0xBB, 0xA3 } Output: 48035 // positive Zahl

Input: {0xFF, 0x44,0x5d } Output: -48.035 // negative Zahl

Der Code funktioniert wie erwartet, aber ich bekomme eine Flusenwarnung. Warnung 648: Überlauf in Rechenkonstante für den Betrieb: 'Multiplikation'

Ich brauche die Funktionalität, aber nicht die Warnung.Wie kann ich es unterdrücken?

+0

Verwenden Sie 'UL' Suffix auf Ihre' 0x1000000' Konstante –

+0

Wenn Sie die Multiplikation als die entsprechende Verschiebung machen, wäre es dann sinnvoll? Denken Sie daran, dass Sie mit "int" arbeiten, was ein ** signierter ** 32-Bit-Typ ist (auf den meisten Plattformen). –

+0

Ein allgemeiner Tipp: Wenn Sie mit Bits arbeiten, verwenden * immer * explizit nicht signierte Datentypen. –

Antwort

2

Sie können Multiplikation mit Bitverschiebung ersetzen oder sogar das Bitmuster manuell für eine bessere Lesbarkeit berechnen:

const int32 bMSBNeg = (int32)0xFF000000; 

Sie können auch all diese Berechnungen vermeiden, indem die Anzahl in den oberen drei Bytes konstruieren, und dann verschieben es durch 8 Bits mit der Division nach unten:

if (pbData != NULL) { 
    i32Num = ((pbData[0] << 24) | (pbData[1] << 16) | (pbData[2] << 8))/256; 
} 

Anmerkung: 8 durch Verschiebung statt durch 256 dividiert nach Implementierung definierte Verhalten auf den Standard wären.

+1

Ihre erste Zeile ist eine Zuweisung außerhalb des Bereichs (es gibt ein paar Probleme beim Entpacken negativer Werte; wenn OP implementationsdefiniertes Verhalten vermeiden möchte, müssen wir vorsichtig sein) –

+0

C11 Normentwurf n1570: * 6.5.7 Bitweise Verschiebeoperatoren 5 Das Ergebnis von E1 >> E2 ist E1 rechtsverschobene E2 Bitpositionen. [...] Wenn E1 einen signierten Typ und einen negativen Wert hat, ist der resultierende Wert implementierungsdefiniert. * – EOF

+1

@EOF Ups, der lästige Standard mit seinem implementierungsdefinierten Verhalten hat mich wieder erreicht. Ich sollte stattdessen Division durch 256 verwenden. – dasblinkenlight

Verwandte Themen