Kako nastavite, počistite in preklopite bit?
Za nastavitev bita uporabite bitni operator OR (|
).
number |= 1UL << n;
To bo nastavilo n
ti bit števila številke
. n
mora biti nič, če želite nastaviti prvi bit, in tako naprej do
n-1, če želite nastaviti
n`ti bit.
Uporabite 1ULL
, če je število
širše od unsigned long
; promocija 1UL << n
se zgodi šele po ovrednotenju 1UL << n
, kjer je premik za več kot širino long
nedefinirano vedenje. Enako velja za vse ostale primere.
Za brisanje bita uporabite bitni operator AND (&
).
number &= ~(1UL << n);
To bo počistilo n
ti bit števila številke
. Niz bitov morate obrniti z bitnim operatorjem NOT (`~``), nato pa še z AND.
Operator XOR (^
) lahko uporabite za preklapljanje bitov.
number ^= 1UL << n;
To bo preklopilo n
ti bit številke
.
Tega niste vprašali, vendar ga lahko dodam.
Če želite preveriti bit, premaknite število n na desno, nato pa ga bitno povežite:
bit = (number >> n) & 1U;
Vrednost n-tega bita števila
številkase bo prenesla v spremenljivko
bit`.
Nastavitev n
tega bita na 1
ali 0
lahko v implementaciji C++ z 2'komplementom dosežemo z naslednjim:
number ^= (-x ^ number) & (1UL << n);
Bit n
bo nastavljen, če je x
1
, in izbrisan, če je x
0
. Če ima x
kakšno drugo vrednost, dobimo smeti. x = !!x
ga bo booleaniziral na 0 ali 1.
Da bi bilo to neodvisno od obnašanja negacije z 2'komplementom (kjer ima -1
nastavljene vse bite, za razliko od implementacije 1'komplementa ali znaka/veličine v C++), uporabite negacijo z nezaznamovanim številom.
number ^= (-(unsigned long)x ^ number) & (1UL << n);
ali
unsigned long newbit = !!x; // Also booleanize to force 0 or 1
number ^= (-newbit ^ number) & (1UL << n);
Na splošno je za prenosno manipulacijo z biti dobro uporabljati nezaznamovane tipe.
ali
number = (number & ~(1UL << n)) | (x << n);
(number & ~(1UL << n))
bo izbrisal n
ti bit, (x << n)
pa bo n
ti bit nastavil na x
.
Na splošno je tudi dobro, da ne kopiramo/prilepljamo kode na splošno, zato veliko ljudi uporablja makroje v predprocesorju (kot odgovor na skupnostnem wikiju v nadaljevanju) ali neke vrste enkapsulacijo.
Včasih je vredno uporabiti enum
za imenovanje bitov:
enum ThingFlags = {
ThingMask = 0x0000,
ThingFlag0 = 1 << 0,
ThingFlag1 = 1 << 1,
ThingError = 1 << 8,
}
Nato uporabite imena kasneje. Tj. napišite
thingstate |= ThingFlag1;
thingstate &= ~ThingFlag0;
if (thing & ThingError) {...}
za nastavitev, brisanje in testiranje. Na ta način skrijete čarobne številke pred preostalo kodo.
Razen tega podpiram Jeremyjevo rešitev.
Uporabite bitne operatorje: &
|
Za nastavitev zadnjega bita v 000b
:
foo = foo | 001b
Preverjanje zadnjega bita v foo
:
if ( foo & 001b ) ....
Izbrisati zadnji bit v foo
:
foo = foo & 110b
Zaradi jasnosti sem uporabil XXXb
. Glede na podatkovno strukturo, v katero pakirate bite, boste verjetno delali s predstavitvijo HEX.