Qu'est-ce que does AND 0xFF fait?
Dans le code suivant:
short = ((byte2 << 8) | (byte1 & 0xFF))
Quel est le but de &0xFF?
Parce que d'autres estiment que je le vois écrit comme:
short = ((byte2 << 8) | byte1)
et ça a l'air de marcher aussi?
7 réponses
Anding un entier 0xFF ne laisse que l'octet le moins significatif. Par exemple, pour obtenir le premier octet dans un short s, vous pouvez écrire s & 0xFF. C'est généralement appelé "masque". Si byte1 est un type octet (comme uint8_t) ou est déjà inférieur à 256 (et par conséquent tous les zéros sauf pour le octet le moins significatif) il n'y a pas besoin de masquer les bits supérieurs, car ils sont déjà zéro.
Voir tristopiaréponse de Patrick Schlüter ci-dessous quand vous pouvez travailler avec des types signés. Lorsque vous effectuez des opérations bitwise, je vous recommande de travailler uniquement avec des types non signés.
si byte1 est un type entier 8 bits alors il est inutile - s'il est supérieur à 8 bits, il vous donnera essentiellement les 8 derniers bits de la valeur:
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
Le danger de la seconde expression vient, si le type de byte1char. Dans ce cas, certaines implémentations peuvent avoir signed char, ce qui entraînera une extension du signal lors de l'évaluation.
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);
value1=4224 1080 right
value2=65408 ff80 wrong!!
j'ai essayé sur gcc v3.4.6 sur Solaris SPARC 64 bit et le résultat est le même avec byte1 et byte2 a déclaré que char.
TL;DR
Le masquage pour éviter implicite signe extension.
EDIT: j'ai vérifié, c'est le même comportement en C++.
en supposant votre byte1 est un octet(8bits), Lorsque vous effectuez une opération de bits ET d'octets avec 0xFF, vous obtenez le même octet.
byte1 est le même que byte1 & 0xFF
byte101001101 , puis byte1 & 0xFF = 01001101 & 11111111 = 01001101 = byte1
si byte1 est d'un autre type dire entier de 4 octets, bitwise et avec 0xFF vous laisse avec le moins significatif byte (8 bits) du byte1.
byte1 & 0xff assure que seuls les 8 bits les moins significatifs de byte1 peut être non nulle.
si byte1 est déjà un type non signé qui n'a que 8 bits (e.g.,char dans certains cas, ou unsigned char dans la plupart des cas) cela ne fera aucune différence/est complètement inutile.
Si byte1 est un type qui est signé ou a plus de 8 bits (par exemple,short,int,long), et tous les bits sauf le 8 le moins significatif est définie, alors il y aura une différence (c'est à dire, il va de zéro ces bits de poids avant or avec l'autre variable, donc cet opérande du or affecte seulement les 8 bits les moins significatifs du résultat).
il efface tous les bits qui ne sont pas dans le premier octet
& 0xFF garantit seulement que si les octets sont plus longs que 8 bits (autorisés par la norme de langue), le reste est ignoré.
Et qui semble bien fonctionner aussi?
si le résultat est supérieur à SHRT_MAX, vous obtenez un comportement indéfini. À cet égard, les deux ne fonctionneront pas aussi bien.