练习 2-9
在求对二的补码时,表达式 x &= (x – 1)可以删除 x 中最右边值为 1 的
一个二进制位。请解释这样做的道理。用这一方法重写 bitcount 函数,以加快其执行速度。
#include <stdio.h>
main()
{
int x = 123; //0111_1011
int b;
for (b = 0; x != 0; b++)
x &= x - 1;
printf("%d\n", b);
/*
x &= (x - 1)
相当于 :
x = x & (x - 1)
此表达式会干掉x最右边的1。
通过推算就能看出来
暂时称&左边的二进制数为1号,&右边的二进制数为2号
先来看1号最右位为1的情况:
if
x = 0111_1011
when
x = 0111_1011 & (0111_1011 - 0000_0001)
= 0111_1011 & 0111_1010
x = 0111_1010
“&”是按位与,
1号与2号唯一的差别就是最右位,
其他位&后结果不变
最右位 1&0,得0
结果是0111_1010
就相当于把最右边一个1干掉了
-------------------------------------------------------
现在1号最右位为0:
if
x = 0111_1010
when
x = 0111_1010 & (0111_1010 - 0000_0001)
= 0111_1010 & 0111_1001
2号的值为1号减一(0111_1010 - 0000_0001)
1号的最右位是0,发生了借位
其实就是(0111_1002 - 0000_0001) = 0111_1001
2号的值是0111_1001
然后1号和2号进行&运算:
0111_1010
& 0111_1001
可以看到1号和2号有两位不同,
0&1得0,这两位都被干掉了
最终结果是0111_1000
x最右边的1被干掉了
--------------------------------------------------------
无论 x 最右边的数是1还是0,
x =& (x-1)都可以把最右边的一个1干掉
*/
}
写注释真的好恶心啊...( ̄ェ ̄;)