Подтвердить что ты не робот

Функция, чтобы проверить, установлен ли n-й бит в байте

Мне нужна простая функция C, которая вернет true, если n-й бит в байте установлен на 1. В противном случае он вернет false.

Это критическая функция с точки зрения времени выполнения, поэтому я думаю о наиболее оптимальном способе сделать это.

4b9b3361

Ответ 1

Следующая функция может делать то, что вам нужно:

int isNthBitSet (unsigned char c, int n) {
    static unsigned char mask[] = {128, 64, 32, 16, 8, 4, 2, 1};
    return ((c & mask[n]) != 0);
}

Это предполагает 8-разрядные байты (не заданные в C), а нулевой бит - самый старший. Если это допущение неверно, оно просто сводится к расширению и/или переупорядочению массива mask.

Проверка ошибок не выполняется, поскольку вы указали скорость как наиболее важное соображение. Не передавайте недопустимый n, который будет undefined.

При безумном уровне оптимизации -O3 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

который довольно мал и эффективен. И если вы сделаете его статическим и предложите встраивание или принудительно установите его как макроопределение, вы можете даже обойти стоимость вызова функции.

Просто убедитесь, что вы оцениваете любое решение, которое вам дано, включая этот (a). Мантра номер один в оптимизации - "Мера, не угадайте!"

Если вы хотите знать, как работают побитовые операторы, см. здесь. Упрощенная версия AND доступна ниже.

Операция AND & устанавливает бит в цель только в том случае, если оба бита установлены в источниках tewo. Соответствующая таблица:

AND | 0 1
----+----
 0  | 0 0
 1  | 0 1

При заданном значении char мы используем однобитовые битовые маски, чтобы проверить, установлен ли бит. Скажем, у вас есть значение 13, и вы хотите увидеть, установлен ли бит третьего с наименьшего значения.

Decimal  Binary
  13     0000 1101
   4     0000 0100 (the bitmask for the third-from-least bit).
         =========
         0000 0100 (the result of the AND operation).

Вы можете видеть, что все нулевые биты в маске приводят к тому, что эквивалентные биты результата равны нулю. Один бит в маске будет в основном пропускать эквивалентный бит в потоке значения к результату. Результат равен нулю, если бит, который мы проверяем, равен нулю или не равен нулю, если он был одним.

То, откуда приходит выражение в выражении return. Значения в таблице поиска mask - это все однобитовые маски:

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) Я знаю, насколько я хорош, но вы этого не делаете: -)

Ответ 2

Просто проверьте значение (1 << bit) & byte. Если он отличен от нуля, бит устанавливается.

Ответ 3

Пусть число будет num. Тогда:

return ((1 << n) & num);

Ответ 4

bool isSet(unsigned char b, unsigned char n) { return b & ( 1 << n); }

Ответ 5

#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);
}   

Ответ 6

Другим подходом будет

    bool isNthBitSet (unsigned char c, int n) {
      return (1 & (c >> n));
    }