Was macht AND 0xFF?

Beim Einfügen einer Ganzzahl mit 0xFFbleibt nur das niedrigstwertige Byte übrig. Um beispielsweise das erste Byte in einem short s zu erhalten, können Sie s & 0xFF schreiben. Dies wird typischerweise als „Maskierung“ bezeichnet. Wenn byte1 entweder ein einzelner Bytetyp ist (wie uint8_t) oder bereits kleiner als 256 ist (und infolgedessen alle Nullen mit Ausnahme des niedrigstwertigen Bytes sind), müssen die höheren Bits nicht maskiert werden, da sie bereits Null sind.

Siehe die Antwort von tristopiaPatrick Schlüter unten, wenn Sie möglicherweise mit signierten Typen arbeiten. Bei bitweisen Operationen empfehle ich, nur mit vorzeichenlosen Typen zu arbeiten.

Wenn byte1 ein 8-Bit-Integer-Typ ist, dann ist es sinnlos – wenn es mehr als 8 Bit ist, wird es Ihnen im Wesentlichen die letzten 8 Bits des Wertes geben:

 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 & 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 ------------------------------- 0 0 0 0 0 0 0 0 0 1 0 1 0 1 0 1

Die Gefahr des zweiten Ausdrucks besteht, wenn der Typ von byte1 char ist. In diesem Fall können einige Implementierungen es signed char haben, was bei der Auswertung zu einer Vorzeichenerweiterung führt.

signed char byte1 = 0x80;signed char byte2 = 0x10;unsigned short value1 = ((byte2 << 8) | (byte1 & 0xFF));unsigned short value2 = ((byte2 << 8) | byte1);printf("value1=%hu %hx\n", value1, value1);printf("value2=%hu %hx\n", value2, value2);

wird gedruckt

value1=4224 1080 rightvalue2=65408 ff80 wrong!!

Ich habe es auf gcc v3.4 versucht.6 auf Solaris SPARC 64 Bit und das Ergebnis ist das gleiche mit byte1 und byte2 als char deklariert.

TL; DR

Die Maskierung besteht darin, eine implizite Vorzeichenerweiterung zu vermeiden.

BEARBEITEN: Ich habe überprüft, es ist das gleiche Verhalten in C ++.

EDIT2: Wie gewünscht Erklärung der Zeichenerweiterung.Die Vorzeichenerweiterung ist eine Folge der Art und Weise, wie C Ausdrücke auswertet. In C gibt es eine Regel namens Promotionsregel. C konvertiert implizit alle kleinen Typen in int , bevor die Auswertung durchgeführt wird. Mal sehen, was mit unserem Ausdruck passiert:

unsigned short value2 = ((byte2 << 8) | byte1);

byte1 ist eine Variable, die das Bitmuster 0xFF enthält. Wenn char unsigned ist, wird dieser Wert als 255 interpretiert, wenn er signed ist, ist er -128. Bei der Berechnung erweitert C den Wert auf eine Größe int (im Allgemeinen 16 oder 32 Bit). Dies bedeutet, dass, wenn die Variable unsigned ist und wir den Wert 255 behalten, das Bitmuster dieses Wertes als int 0x000000FF ist. Wenn es signed ist, wollen wir den Wert -128, dessen Bitmuster 0xFFFFFFFF ist. Das Zeichen wurde auf die Größe der zur Berechnung verwendeten Zeit erweitert.Und so wird das temporäre Oring das falsche Ergebnis liefern.

Bei der x86-Assembly erfolgt dies mit der Anweisung movsx (movzx für die Nullerweiterung). Andere CPUs hatten andere Anweisungen dafür (6809 hatte SEX).

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht.