您的位置:首页 > 编程语言 > C语言/C++

《C程序设计语言》练习 2-9

2017-12-29 10:46 225 查看
练习 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干掉
*/
}

写注释真的好恶心啊...( ̄ェ ̄;)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息