Ich möchte eine einfache C-Funktion, die true zurückgibt, wenn das n-te Bit in einem Byte auf 1
gesetzt ist. Andernfalls wird falsch zurückgegeben.
Dies ist eine kritische Funktion in Bezug auf die Ausführungszeit, daher denke ich an den optimalen Weg, dies zu tun.
Die folgende Funktion kann, was Sie brauchen:
int isNthBitSet (unsigned char c, int n) {
static unsigned char mask[] = {128, 64, 32, 16, 8, 4, 2, 1};
return ((c & mask[n]) != 0);
}
Dies setzt 8-Bit-Bytes (in C nicht gegeben) voraus, und das nullte Bit ist das höchste Bit. Wenn diese Annahme falsch ist, müssen Sie lediglich das mask
-Array erweitern und/oder neu anordnen.
Es wird keine Fehlerprüfung durchgeführt, da Sie Geschwindigkeit als die wichtigste Überlegung angeführt haben. Übergeben Sie not eine ungültige n
, dies ist undefiniertes Verhalten.
Auf der wahnsinnigen Optimierungsstufe -O3
gibt uns gcc:
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
das ist ziemlich klein und effizient. Wenn Sie es statisch machen und Inlining vorschlagen oder es als Makrodefinition erzwingen, können Sie sogar die Kosten eines Funktionsaufrufs umgehen.
Vergewissern Sie sich, dass Sie für jede Lösung, die Sie erhalten, ein Benchmarking durchführen, einschließlich dieser Lösung (ein). Das Mantra Nummer eins in der Optimierung ist "Messen, nicht raten!"
Wenn Sie wissen möchten, wie die bitweisen Operatoren funktionieren, lesen Sie hier . Die vereinfachte UND-Version ist unten aufgeführt.
Die AND-Operation &
setzt nur dann ein Bit im Ziel, wenn beide Bits in den Tewo-Quellen gesetzt sind. Die relevante Tabelle ist:
AND | 0 1
----+----
0 | 0 0
1 | 0 1
Für einen bestimmten char
-Wert verwenden wir die Einzelbit-Bitmasken, um zu prüfen, ob ein Bit gesetzt ist. Nehmen wir an, Sie haben den Wert 13 und möchten sehen, ob das drittniedrigste Bit gesetzt ist.
Decimal Binary
13 0000 1101
4 0000 0100 (the bitmask for the third-from-least bit).
=========
0000 0100 (the result of the AND operation).
Sie können sehen, dass alle Null-Bits in der Maske dazu führen, dass die entsprechenden Ergebnisbits Null sind. Das einzelne Bit in der Maske lässt grundsätzlich das entsprechende Bit im Wert zum Ergebnis durch. Das Ergebnis ist dann Null, wenn das von uns überprüfte Bit Null war, oder nicht Null, wenn es eins war.
Von dort kommt der Ausdruck in der return
-Anweisung. Die Werte in der Nachschlagetabelle mask
sind alle Einzelbitmasken:
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
(ein) I weiß, wie gut ich bin, aber du nicht :-)
Überprüfen Sie einfach den Wert von (1 << bit) & byte
. Wenn es nicht Null ist, wird das Bit gesetzt.
Die Zahl sei num
. Dann:
return ((1 << n) & num);
bool isSet(unsigned char b, unsigned char n) { return b & ( 1 << n); }
#include<stdio.h>
int main()
{
unsigned int n,a;
printf("enter value for n\n");
scanf("%u",&n);
pintf("enter value for a:\n");
scanf("%u",&a);
a= a|(((~((unsigned)0))>>(sizeof(int)*8-1))<<n);
printf("%u\n",a);
}
Ein anderer Ansatz wäre
bool isNthBitSet (unsigned char c, int n) {
return (1 & (c >> n));
}
#include<stdio.h>
int main()
{
int data,bit;
printf("enter data:");
scanf("%d",&data);
printf("enter bit position to test:");
scanf("%d",&bit);
data&(1<<bit)?printf("bit is set\n"):printf("bit is clear\n");
return 0;
}