我正在阅读一个包含以下功能的程序,即
int f(int n) {
int c;
for (c=0;n!=0;++c)
n=n&(n-1);
return c;
}
我不太明白这个功能打算做什么?
答案 0 :(得分:36)
n {/ 3>的二进制表示中的counts number of 1's
答案 1 :(得分:11)
旨在说明评论的重要性。
答案 2 :(得分:6)
该函数是INTENDED以返回n表示中的位数。在其他答案中错过的是,该函数调用参数n<的未定义行为。这是因为该函数从最低位到最高位一次剥离一位数。对于负数字,这意味着,循环终止前的n的最后一个值(对于2补码中的32位整数)是0x8000000。这个数字是INT_MIN,现在它最后一次在循环中使用:
n = n&(n-1)
不幸的是,INT_MIN-1是溢出并且溢出调用未定义的行为。一个符合要求的实现不需要“环绕”整数,例如它可以发出溢出陷阱或留下各种奇怪的结果。
答案 3 :(得分:4)
对于非军用cpu中缺少POPCNT指令,这是一个(现已过时)的解决方法。
答案 4 :(得分:3)
这计算了使用二进制文件将n
减少到0
所需的迭代次数。
答案 5 :(得分:1)
它显示了一种不编程的方法(对于x86指令集),使用内部/内联汇编程序指令更快更好地读取这样简单的东西。 (但据我所知,这只适用于x86架构,我不知道它是关于ARM或SPARC或其他什么的)
答案 6 :(得分:1)
表达式n = n & (n - 1)
是一个按位运算,它将n
中最右边的位“1”替换为“0”。
例如,取整数5(0101)。然后n & (n - 1)
→(0101) & (0100)
→0100
(从右侧删除第一个'1'位。)
所以上面的代码返回给定整数的二进制形式的1的数字。
答案 7 :(得分:0)
是否可以尝试返回n中的有效位数? (没有完全考虑过它......)