我想要一个简单的C函数,如果一个字节中的第n位设置为1
,它将返回true。否则它将返回false。
这在执行时间方面是一个关键功能,所以我想到了最佳的方法。
答案 0 :(得分:36)
以下功能可以满足您的需求:
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中给出的),第0位是最高位的。如果这些假设不正确,则只需要扩展和/或重新排序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)。优化中的头号口号是“测量,不要猜测!”
如果您想知道按位运算符的工作方式,请参阅here。简化的AND-only版本如下。
只有在tewo源中设置了两个位时,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).
您可以看到掩码中的所有零位导致等效结果位为零。掩码中的单个位基本上会让值中的等效位流入结果。如果我们检查的位为零,则结果为零;如果为1,则结果为非零。
这就是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 :(得分:25)
只需检查(1 << bit) & byte
的值即可。如果它非零,则设置该位。
答案 2 :(得分:10)
让数字为num
。然后:
return ((1 << n) & num);
答案 3 :(得分:4)
bool isSet(unsigned char b, unsigned char n) { return b & ( 1 << n); }
答案 4 :(得分:2)
#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);
}
答案 5 :(得分:2)
另一种方法是
bool isNthBitSet (unsigned char c, int n) {
return (1 & (c >> n));
}
答案 6 :(得分:0)
DataView view = new DataView(this.excelBook.Tables);
DataTable distinctValues = view.ToTable(true, "DataSourceName");