Hoe stel je een bit in, wis je het en schakel je het om?
Gebruik de bitwise OR operator (|
) om een bit in te stellen.
number |= 1UL << n;
Dat zet de n
ste bit van getal
. n
moet nul zijn, als je de 1
ste bit wilt zetten en zo verder tot n-1
, als je de n
ste bit wilt zetten.
Gebruik 1ULL
als getal
breder is dan unsigned long
; promotie van 1UL << n
gebeurt pas na evaluatie van 1UL << n
waar het's ongedefinieerd gedrag is om met meer dan de breedte van een long
te verschuiven. Hetzelfde geldt voor de rest van de voorbeelden.
Gebruik de bitwise AND operator (&
) om een bit te wissen.
number &= ~(1UL << n);
Dat wist het n
de bit van getal
. Je moet de bit string omkeren met de bitwise NOT operator (~
), en dan AND-en.
De XOR operator (^
) kan gebruikt worden om een bit te wisselen.
number ^= 1UL << n;
Daarmee schakel je het n
de bit van getal
om.
Je hebt hier niet om gevraagd, maar ik kan het net zo goed toevoegen.
Om een bit te controleren, verschuif je het getal n naar rechts, en dan bitwise AND het:
bit = (number >> n) & 1U;
Dat zal de waarde van het n
de bit van getal
in de variabele bit
zetten.
Het instellen van de n
e bit op 1
of 0
kan worden bereikt met het volgende op een 2's complement C++ implementatie:
number ^= (-x ^ number) & (1UL << n);
Bit n
wordt gezet als x
1
is, en gewist als x
0
is. Als x
een andere waarde heeft, krijg je garbage. x = !!x
booleaniseert het naar 0 of 1.
Om dit onafhankelijk te maken van 2's complement negatie gedrag (waar -1
alle bits gezet heeft, in tegenstelling tot een 1's complement of teken/magnesium C++ implementatie), gebruik je unsigned negatie.
number ^= (-(unsigned long)x ^ number) & (1UL << n);
of
unsigned long newbit = !!x; // Also booleanize to force 0 or 1
number ^= (-newbit ^ number) & (1UL << n);
Het is over het algemeen een goed idee om niet-ondertekende types te gebruiken voor draagbare bitmanipulatie.
of
number = (number & ~(1UL << n)) | (x << n);
(getal & ~(1UL << n))
zal het n
ste bit wissen en (x << n)
zal het n
ste bit op x
zetten.
Het is over het algemeen ook een goed idee om geen code te kopiëren/plakken in het algemeen en daarom gebruiken veel mensen preprocessor macro's (zoals het community wiki antwoord verderop) of een soort inkapseling.
Het is soms de moeite waard om een enum
te gebruiken om de bits een naam te geven:
enum ThingFlags = {
ThingMask = 0x0000,
ThingFlag0 = 1 << 0,
ThingFlag1 = 1 << 1,
ThingError = 1 << 8,
}
Gebruik de namen dan later. Ik schrijf bijvoorbeeld
thingstate |= ThingFlag1;
thingstate &= ~ThingFlag0;
if (thing & ThingError) {...}
om in te stellen, te wissen en te testen. Op deze manier verberg je de magische getallen voor de rest van je code.
Voor de rest ben ik het eens met Jeremy's oplossing.
Gebruik de bitwise operatoren: &
|
Om het laatste bit in 000b
te zetten:
foo = foo | 001b
Om het laatste bit in foo
te controleren:
if ( foo & 001b ) ....
Om het laatste bit in foo
te wissen:
foo = foo & 110b
Ik heb XXXb
gebruikt voor de duidelijkheid. Je zult waarschijnlijk met HEX representatie werken, afhankelijk van de datastructuur waarin je bits verpakt.