《编程之美》中2.1 求二进制数中1的个数,就找到这题来做,1AC,可是代码不够优化,看到discuss中牛人的代码,发现M神博客中的解释。
#include <stdio.h>
int main()
{
int n, x;
while (scanf("%d", &n), n)
{
x = n & -n;
printf("%d\n", n + x + (n ^ n + x) / x / 4);
}
}
位运算当中很多应用到了2的n次幂的性质。
n & -n :计算最右边1的位置:2的n次幂的补还是其本身(不带符号)。例如:101000 & 011000 = 001000
n + x :把右侧连续的1变成1000...的形式。例如:1011100 + 100 = 1100000
n ^ (n + x):取新得到的1和连续的1相连。例如:1011100 ^ 1100000 = 0111100
/ x / 4 :右移两位,再右移x位补差的1到最后的位置上