La "valeur" va de 0 à 15 (ses valeurs possibles). Quand ces 4 conditions "si" seront-elles remplies? Si ma valeur (int) = 2, cela signifie-t-il 0010?
if ((int)value & 0x1)
{
//statement here
}
if ((int)value & 0x2)
{
//statement here
}
if ((int)value & 0x4)
{
//statement here
}
if ((int)value & 0x8)
{
//statement here
}
Chaque nombre peut être exprimé par value = b0*2^0 + b1*2^1 + b2*2^2 + b3*2^3 + ...
avec chaque b soit 0
ou 1
(ce sont les bits de la représentation). Ceci est la représentation binaire.
Le binaire ET (&
) prend chacun de ces b
paire par sage et effectue AND sur eux. Cela a les sorties suivantes:
0 & 0 = 0
0 & 1 = 0
1 & 0 = 0
1 & 1 = 1
En utilisant des puissances de 2 (qui n'ont qu'un seul bit activé), nous pouvons isoler et tester les bits individuels:
value & 1
est vrai lorsque value
est impair {1, 3, 5, 7, 9, 11, 13, 15}.
value & 2
est vrai lorsque value/2
est impair {2, 3, 6, 7, 10, 11, 14, 15}.
value & 4
est vrai lorsque value/4
est impair {4, 5, 6, 7, 12, 13, 14, 15}.
value & 8
est vrai lorsque value/8
est impair {8, 9, 10, 11, 12, 13, 14, 15}.
Le préfixe 0x sur les nombres signifie qu'il doit être interprété comme nombre hexadécimal . C'est un peu superflu lorsque vous ne montez qu'à 0x8, mais vous dites aux responsables qu'il est probablement utilisé comme masque de bits.
Ces instructions if vérifient si un bit spécifique de value
est défini.
La valeur hexadécimale 0x4
, par exemple, a le 3e bit du jeu de droite à 1
et tous les autres bits définis sur 0
. Lorsque vous utilisez l'opérateur binaire et (&
) avec deux opérants, le résultat aura tous les bits définis sur 0
sauf pour les bits qui sont 1 dans les deux opérateurs.
Ainsi, lorsque vous effectuez le calcul value & 0x4
, vous obtenez soit binaire 00000000
ou binaire 00000100
, selon que le 3e bit de value
est ou non 1
ou 0
. Le premier est évalué à false
, et le second à true
, donc le bloc if n'est exécuté que pour les valeurs où le 3ème bit est défini.
Il y a deux choses intéressantes à noter ici.
Tout d'abord, il s'agit d'un modèle commun pour vérifier chacun des 4 bits de poids faible d'une valeur intégrale. La condition if est remplie si le bit correspondant est activé. Pour la valeur 2, le motif binaire est bien 0010.
L'autre question plus intéressante est pourquoi le (int)
cast? Mis à part le mauvais style d'utilisation des transtypages C en C++, aucune valeur entière ou de caractère ne nécessite cette conversion. Un bool n'a aucun sens, un double/float serait converti en un entier temporaire et il serait inhabituel d'utiliser des valeurs littérales pour tester une énumération. Cela pourrait avoir un sens avec un pointeur, mais ce serait une utilisation très spécialisée. Conclusion: le casting n'a aucun sens.