Come si fa a impostare, cancellare e alternare un bit?
Usate l'operatore bitwise OR (|
) per impostare un bit.
number |= 1UL << n;
Questo imposterà il n'esimo bit di
numero.
ndovrebbe essere zero, se vuoi impostare il
1° bit e così via fino a
n-1, se vuoi impostare il
n`° bit.
Usate 1ULL
se numero
è più largo di unsigned long
; la promozione di 1UL << n
non avviene fino a dopo la valutazione di 1UL << n
dove è un comportamento non definito spostare di più della larghezza di un long
. Lo stesso vale per tutto il resto degli esempi.
Usa l'operatore bitwise AND (&
) per cancellare un bit.
number &= ~(1UL << n);
Questo cancellerà il n'esimo bit di
numero. Devi invertire la stringa di bit con l'operatore bitwise NOT (
~`), poi AND.
L'operatore XOR (^
) può essere usato per cambiare un bit.
number ^= 1UL << n;
Questo commuterà il n'esimo bit di
numero`.
Non l'avete chiesto, ma potrei anche aggiungerlo.
Per controllare un bit, sposta il numero n a destra, poi fai un AND bitwise:
bit = (number >> n) & 1U;
Questo metterà il valore del n'esimo bit del
numeronella variabile
bit`.
Impostare il n'esimo bit a
1o
0` può essere ottenuto con il seguente su un'implementazione C++ a complemento di 2:
number ^= (-x ^ number) & (1UL << n);
Il bit n
sarà impostato se x
è 1
, e cancellato se x
è 0
. Se x
ha qualche altro valore, si ottiene spazzatura. x = !!x
lo booleanizzerà a 0 o 1.
Per rendere questo indipendente dal comportamento della negazione del complemento a 2 (dove -1
ha tutti i bit impostati, a differenza dell'implementazione del complemento a 1 o del segno/magnitudine del C++), usate la negazione senza segno.
number ^= (-(unsigned long)x ^ number) & (1UL << n);
o
unsigned long newbit = !!x; // Also booleanize to force 0 or 1
number ^= (-newbit ^ number) & (1UL << n);
È generalmente una buona idea usare tipi senza segno per la manipolazione portatile dei bit.
o
number = (number & ~(1UL << n)) | (x << n);
(number & ~(1UL << n))
cancellerà il n'esimo bit e
(x << n)imposterà il
n'esimo bit su x
.
È anche generalmente una buona idea non copiare/incollare il codice in generale e così molte persone usano macro del preprocessore (come la risposta del wiki della comunità più in basso) o qualche tipo di incapsulamento.
A volte vale la pena usare un enum
per nominare i bit:
enum ThingFlags = {
ThingMask = 0x0000,
ThingFlag0 = 1 << 0,
ThingFlag1 = 1 << 1,
ThingError = 1 << 8,
}
Poi usare i nomi in seguito. Per esempio, scrivete
thingstate |= ThingFlag1;
thingstate &= ~ThingFlag0;
if (thing & ThingError) {...}
per impostare, cancellare e testare. In questo modo nascondi i numeri magici dal resto del tuo codice.
A parte questo, approvo la soluzione di Jeremy.
Usate gli operatori bitwise: &
|
Per impostare l'ultimo bit in 000b
:
foo = foo | 001b
Per controllare l'ultimo bit in foo
:
if ( foo & 001b ) ....
Per cancellare l'ultimo bit in foo
:
foo = foo & 110b
Ho usato XXXb
per chiarezza. Probabilmente lavorerai con la rappresentazione HEX, a seconda della struttura dei dati in cui stai impacchettando i bit.