liv*_*hak 19 c bit-manipulation
我想要一个简单的C函数,如果一个字节中的第n位被设置为,它将返回true 1.否则它将返回false.
这在执行时间方面是一个关键功能,因此我正在考虑最佳的方法.
pax*_*blo 37
以下功能可以满足您的需求:
int isNthBitSet (unsigned char c, int n) {
static unsigned char mask[] = {128, 64, 32, 16, 8, 4, 2, 1};
return ((c & mask[n]) != 0);
}
Run Code Online (Sandbox Code Playgroud)
这假定为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
Run Code Online (Sandbox Code Playgroud)
这是非常小而有效的.如果你使它静态并建议内联,或强制它内联作为宏定义,你甚至可以绕过函数调用的成本.
只要确保你对你给出的任何解决方案进行基准测试,包括这个(a).优化中的头号口号是"措施,不要猜!"
如果您想知道按位运算符的工作方式,请参见此处.简化的AND-only版本如下.
&仅当两个位在tewo源中设置时,AND操作才会在目标中设置一个位.相关表格是:
AND | 0 1
----+----
0 | 0 0
1 | 0 1
Run Code Online (Sandbox Code Playgroud)
对于给定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).
Run Code Online (Sandbox Code Playgroud)
您可以看到掩码中的所有零位导致等效结果位为零.掩码中的单个位基本上会让值中的等效位流入结果.如果我们检查的位为零,则结果为零;如果为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
Run Code Online (Sandbox Code Playgroud)
(a) 我知道我有多好,但你没有:-)