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?

32
demandé sur Muis 2013-02-05 21:14:59

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.

29
répondu John Colanduoni 2015-10-07 09:30:50

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
22
répondu D Stanley 2013-02-05 17:18:59

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);

print

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++.

19
répondu Patrick Schlüter 2016-04-06 07:37:07

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.

6
répondu Sibi Rajasekaran 2013-02-05 17:25:07

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).

3
répondu Jerry Coffin 2013-02-05 18:01:13

il efface tous les bits qui ne sont pas dans le premier octet

1
répondu thumbmunkeys 2013-02-05 17:17:20

& 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.

0
répondu Alexey Frunze 2013-02-05 17:29:54