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

本文介绍了如何利用C语言中的位运算技巧,通过表达式 x &= (x – 1)来删除二进制数中右侧的最高位1,以此加速bitcount函数的执行,详细解释了该方法的原理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

练习 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干掉
    */
}

写注释真的好恶心啊...( ̄ェ ̄;)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值