Следующая функция может делать то, что вам нужно:
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
, это будет неопределенное поведение.
На безумном уровне оптимизации -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 | 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
(а) Я знаю, насколько я хорош, но вы не знаете: -)