La seguente funzione può fare ciò è necessario:
int isNthBitSet (unsigned char c, int n) {
static unsigned char mask[] = {128, 64, 32, 16, 8, 4, 2, 1};
return ((c & mask[n]) != 0);
}
Questa assume byte di 8 bit (non un dato in C) e il bit zeroth essendo dell'ordine più alto. Se queste ipotesi non sono corrette, si tratta semplicemente di espandere e/o riordinare l'array mask
.
Nessun controllo degli errori viene eseguito poiché si è citato la velocità come la considerazione più importante. Non inviare non pass in uno n
non valido, il comportamento sarà indefinito.
A folle livello di ottimizzazione -O3
, gcc ci dà:
isNthBitSet: pushl %ebp
movl %esp, %ebp
movl 12(%ebp), %eax
movzbl 8(%ebp), %edx
popl %ebp
testb %dl, mask(%eax)
setne %al
movzbl %al, %eax
ret
mask: .byte -128, 64, 32, 16, 8, 4, 2, 1
che è piuttosto piccolo ed efficiente. E se lo rendi statico e suggerisci l'inlining, o lo imponi in linea come una definizione di macro, puoi anche bypassare il costo di una chiamata di funzione.
Assicurati solo di confrontare qualsiasi soluzione che ti è stata fornita, incluso questo (a). Il mantra numero uno nell'ottimizzazione è "Misura, non indovinare!"
Se si desidera sapere come funzionano gli operatori bit a bit, vedere here. La versione semplificata AND-only è sotto.
L'operazione AND &
imposterà un bit nella destinazione solo se entrambi i bit sono impostati nelle sorgenti tewo. Relativa tabella è:
AND | 0 1
----+----
0 | 0 0
1 | 0 1
Per un dato valore char
, usiamo le maschere bit singolo bit per verificare se un bit è impostato. Diciamo che hai il valore 13 e vuoi vedere se è impostato il bit dal terzo meno significativo.
Decimal Binary
13 0000 1101
4 0000 0100 (the bitmask for the third-from-least bit).
=========
0000 0100 (the result of the AND operation).
Si può vedere che tutti i bit zero nella maschera danno come risultato zero bit di risultato equivalenti. Il singolo bit della maschera lascerà fondamentalmente il bit equivalente nel flusso del valore fino al risultato. Il risultato è quindi zero se il bit che stiamo verificando era zero o diverso da zero se era uno.
Ecco da dove viene l'espressione nell'istruzione return
. I valori nella tabella di ricerca mask
sono tutte le maschere single-bit:
Decimal Binary
128 1000 0000
64 0100 0000
32 0010 0000
16 0001 0000
8 0000 1000
4 0000 0100
2 0000 0010
1 0000 0001
(a)I so quanto sono bravo, ma non lo faccio :-)
duplicato, http://stackoverflow.com/questions/523724/cc-check-if-one-bit-is -set-in-ie-int-variable – blueshift
Questo non è un problema, ha chiesto in particolare i metodi ** non-bitshift **. – paxdiablo