Comment régler, effacer et basculer un bit ?
Utilisez l'opérateur OU par bit (|
) pour définir un bit.
number |= 1UL << n;
Cela activera le n
ième bit du nombre
. n
doit être zéro, si vous voulez activer le 1
ème bit et ainsi de suite jusqu'à n-1
, si vous voulez activer le n
ème bit.
Utilisez 1ULL
si number
est plus large que unsigned long
; la promotion de 1UL << n
n'a lieu qu'après l'évaluation de 1UL << n
où c'est un comportement indéfini de décaler de plus que la largeur d'un long
. Il en va de même pour tout le reste des exemples.
Utilisez l'opérateur AND au sens du bit (&
) pour effacer un bit.
number &= ~(1UL << n);
Cela effacera le n
ième bit du nombre
. Vous devez inverser la chaîne de bits avec l'opérateur NOT (~
), puis l'ET.
L'opérateur XOR (^
) peut être utilisé pour basculer un bit.
number ^= 1UL << n;
Cela fera basculer le n
ième bit de number
.
Vous ne l'avez pas demandé, mais je pourrais tout aussi bien l'ajouter.
Pour vérifier un bit, décalez le nombre n vers la droite, puis faites un ET bit à bit :
bit = (number >> n) & 1U;
Cela mettra la valeur du n
ième bit de nombre
dans la variable bit
.
Définir le n
ième bit à 1
ou 0
peut être réalisé avec ce qui suit sur une implémentation C++ du complément à 2 :
number ^= (-x ^ number) & (1UL << n);
Le bit n
sera activé si x
est 1
, et désactivé si x
est 0
. Si x
a une autre valeur, vous obtenez un déchet. x = !!x
le rendra booléen à 0 ou 1.
Pour que cela soit indépendant du comportement de la négation en complément à 2 (où -1
a tous les bits activés, contrairement à une implémentation C++ en complément à 1 ou en signe/magnitude), utilisez la négation non signée.
number ^= (-(unsigned long)x ^ number) & (1UL << n);
ou
unsigned long newbit = !!x; // Also booleanize to force 0 or 1
number ^= (-newbit ^ number) & (1UL << n);
C'est généralement une bonne idée d'utiliser des types non signés pour la manipulation portable des bits.
ou
number = (number & ~(1UL << n)) | (x << n);
(nombre & ~(1UL << n))
effacera le n
ième bit et (x << n)
mettra le n
ième bit à x
.
C'est aussi une bonne idée de ne pas copier/coller du code en général et donc beaucoup de gens utilisent des macros de préprocesseur (comme la réponse du wiki communautaire plus bas) ou une sorte d'encapsulation.
Il est parfois utile d'utiliser un enum
pour nommer les bits :
enum ThingFlags = {
ThingMask = 0x0000,
ThingFlag0 = 1 << 0,
ThingFlag1 = 1 << 1,
ThingError = 1 << 8,
}
Puis d'utiliser les noms plus tard. Par exemple, écrivez
thingstate |= ThingFlag1;
thingstate &= ~ThingFlag0;
if (thing & ThingError) {...}
pour définir, effacer et tester. De cette façon, vous cachez les chiffres magiques du reste de votre code.
À part cela, j'approuve la solution de Jeremy.
Utilisez les opérateurs binaires : &
|
Pour définir le dernier bit de 000b
:
foo = foo | 001b
Vérifier le dernier bit de foo
:
if ( foo & 001b ) ....
Effacer le dernier bit de foo
:
foo = foo & 110b
J'ai utilisé XXXb
pour plus de clarté. Vous travaillerez probablement avec la représentation HEX, en fonction de la structure de données dans laquelle vous empaquetez les bits.