Мне нужна простая функция C, которая вернет true, если n-й бит в байте установлен на 1
. В противном случае он вернет false.
Это критическая функция с точки зрения времени выполнения, поэтому я думаю о наиболее оптимальном способе сделать это.
Мне нужна простая функция C, которая вернет true, если n-й бит в байте установлен на 1
. В противном случае он вернет false.
Это критическая функция с точки зрения времени выполнения, поэтому я думаю о наиболее оптимальном способе сделать это.
Следующая функция может делать то, что вам нужно:
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) Я знаю, насколько я хорош, но вы этого не делаете: -)
Просто проверьте значение (1 << bit) & byte
. Если он отличен от нуля, бит устанавливается.
Пусть число будет num
. Тогда:
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);
}
Другим подходом будет
bool isNthBitSet (unsigned char c, int n) {
return (1 & (c >> n));
}