C++ 计算位或查找最右|最左位的高效按位操作
给定一个无符号int,我必须实现以下操作:C++ 计算位或查找最右|最左位的高效按位操作,c++,c,binary,bit-manipulation,bits,C++,C,Binary,Bit Manipulation,Bits,给定一个无符号int,我必须实现以下操作: 计算设置为1的位数 查找最左边1位的索引 查找最右边1位的索引 (操作不应与体系结构相关) 我已经使用逐位移位完成了这项工作,但是我必须迭代几乎所有的位(es.32)。 例如,计算1: unsigned int number= ...; while(number != 0){ if ((number & 0x01) != 0) ++count; number >>=1; } 其他操作与此类似 所以我
unsigned int number= ...;
while(number != 0){
if ((number & 0x01) != 0)
++count;
number >>=1;
}
其他操作与此类似
所以我的问题是:有没有更快的方法可以做到这一点?看看ffs(3)、ffsl(3)、fls(3)、flsl(3)
ffs()和ffsl()函数查找i中的第一个位集(从最低有效位开始),并返回该位的索引
fls()和flsl()函数查找i中设置的最后一位,并返回该位的索引
您可能也对位字符串(3)感兴趣。如果您想要最快的方法,您将需要使用不可移植的方法
Windows/MSVC:
unsigned int v; // count bits set in this (32-bit value)
unsigned int c; // store the total here
v = v - ((v >> 1) & 0x55555555); // reuse input as temporary
v = (v & 0x33333333) + ((v >> 2) & 0x33333333); // temp
c = ((v + (v >> 4) & 0xF0F0F0F) * 0x1010101) >> 24; // count
最佳位计数方法只需要12次操作,这与查找表方法相同,但避免了表的内存和潜在缓存未命中。它是上述纯并行方法和早期使用乘法的方法(在使用64位指令计算位的部分中)的混合,尽管它不使用64位指令。字节中设置的位的计数并行进行,字节中设置的位的总和通过乘以0x1010101并右移24位来计算
数字x的“最右1位”由以下公式给出
pos(1st '1') = log_2(x XOR (x-1) + 1) - 1
例如:
最后一行的base2日志将为您提供正确的位置+1。因此,从日志结果中减去1,您将得到最正确的“1”位
对于最右边的“0”位,可以使用
pos(1st '0') = log_2(x XOR (x+1) + 1) - 1
对于最右边的位简单ans 第一种方法 } 第二种方法
}考虑获取一份《黑客之乐》,里面充满了对此类低级操作的讨论。另外:感谢链接。非常有趣。如果只设置了一些位,则效率非常高。这不是平台独立的。
pos(1st '0') = log_2(x XOR (x+1) + 1) - 1
unsigned int getFirstSetBit(int n){
return log2(n & -n) + 1;
unsigned int getFirstSetBit(int n){
return ffs(n);