wake-up-neo.com

eine Funktion zur Überprüfung, ob das n-te Bit in einem Byte gesetzt ist

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.

18
liv2hak

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 :-)

36
paxdiablo

Überprüfen Sie einfach den Wert von (1 << bit) & byte. Wenn es nicht Null ist, wird das Bit gesetzt.

24
Jon

Die Zahl sei num. Dann:

return ((1 << n) & num);
10
Divya
bool isSet(unsigned char b, unsigned char n) { return b & ( 1 << n); }
4
Keith Nicholas
#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);
}   
2
Eswar

Ein anderer Ansatz wäre

    bool isNthBitSet (unsigned char c, int n) {
      return (1 & (c >> n));
    }
2
martemiev
#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;
}
0
Ankit Kumar