Ce ne ET 0xFF faire?
Dans le code suivant:
short = ((byte2 << 8) | (byte1 & 0xFF))
Quel est le but de &0xFF
?
Parce que d'autres somestimes je le vois écrit que:
short = ((byte2 << 8) | byte1)
Et qui semble bien fonctionner aussi?
- Est byte1 de type
uint8_t
? - Oui...
- Alors je suppose que c'est seulement "juste pour être sûr". Probablement celui qui a écrit qu'il était en train d'être en sécurité, juste au cas où quelqu'un change le type de
byte1
, ce qui semble tout à fait probable carbyte2
est déjà pas 8-bits (sinonbyte2 << 8
est 0) - Désolé,
byte2 << 8
fonctionne même sibyte2
est un 8 bits type. Par défaut, les expressions toujours commeint
. Le compilateur voit implicitement l'expression comme((int)byte2) << ((int)8)
- btw,
short
est un mot réservé et ne peut pas être utilisé comme nom de variable.
Vous devez vous connecter pour publier un commentaire.
Anding d'un nombre entier avec
0xFF
ne laisse que l'octet le moins significatif. Par exemple, pour obtenir le premier octet dans unshort s
, vous pouvez écrires & 0xFF
. C'est généralement appelé "masque". Sibyte1
est soit un seul type octet (commeuint8_t
) ou est déjà moins de 256 (et comme un résultat est tous les zéros, sauf pour l'octet le moins significatif) il n'est pas nécessaire pour masquer les bits supérieurs, car ils sont déjà à zéro.Voir
tristopiaPatrick Schlüter la réponse ci-dessous lorsque vous travaillez avec des types signés. Quand vous faites des opérations bit à bit, je recommande de travailler uniquement avec les types non signés.si
byte1
est un entier 8 bits type, alors il est inutile - si elle est de plus de 8 bits, il sera essentiellement vous donner les 8 derniers bits de la valeur:Le danger de la seconde expression vient, si le type de
byte1
estchar
. Dans ce cas, certaines implémentations peuvent avoirsigned char
, qui aura pour conséquence l'extension du signe lors de l'évaluation.imprime
Je l'ai essayé sur gcc v3.4.6 sur Solaris SPARC 64 bits et le résultat est le même avec
byte1
etbyte2
déclaré quechar
.TL;DR
Le masquage pour éviter implicite de l'extension du signe.
MODIFIER: j'ai vérifié, c'est le même comportement qu'en C++.
En supposant que 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.Donc
byte1
est le même quebyte1 & 0xFF
Dire
byte1
est01001101
, puisbyte1 & 0xFF = 01001101 & 11111111 = 01001101 = byte1
Si byte1 est d'un autre type de dire entier de 4 octets, au niveau du bit ET avec 0xFF vous laisse avec moins significatif de l'octet(8 bits) de la byte1.
La
byte1 & 0xff
assure que seuls les 8 bits de poids faible debyte1
peut être non nulle.si
byte1
est déjà un type non signé qui ne dispose que de 8 bits (par exemple,char
dans certains cas, ouunsigned char
en plus), il ne fait aucune différence/est complètement inutile.Si
byte1
est un type qui a 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 avantor
ing avec l'autre variable, de sorte que cet opérande de laor
n'affecte que les 8 bits de poids faible du résultat).byte1
estchar
ousigned char
il est absolument nécessaire.il efface tous les bits qui ne sont pas dans le premier octet
& 0xFF
par elle-même ne garantit que, si les octets sont plus de 8 bits (autorisé par la norme du langage), le reste est ignoré.Si le résultat finit plus de
SHRT_MAX
, vous obtenez un comportement indéfini. À cet égard, les deux fonctionneront tout aussi mal.