求一个数被置为1的bit数目

程序设计中经常遇到用一个数的每个bit表示一个状态,有时需要计算被置为1的bit数目。


方法1. 最直接的方法就是一位一位的判断

U8 nonZeroBitNum(U32 x) {

U8 num = 0;

for(U8 i = 0; i++; i<32)

        num += (x>>i) & 1;  // 右移,与,加 运算,需要三个CPU指令周期

return num;

}


这种方法逻辑简单,但是每个32位数都需要循环32次得出结果


方法2. 利用 (2^N - 1) & 2^N = 0的原理对方法1进行优化

一个无符号数32位数可以表示为,bit31*2^31 + bit30*2^30 + .... + bit1*2^1 + bit0*2^0


U8 nonZeroBitNum(U32 x) {

U8 num = 0;

while(x){

    x &= x-1; // 减,与 运算,需要2个CPU指令周期

    num++; // ++运算,1个CPU指令周期

}

return num;

}

可以看出方法2循环内的运算复杂度与方法1是相同的,考虑到不是所有数据的所有bit都是1,假设所有数据平均有16 bit会被置为1,那么这种方法只需要循环16次既可以算出结果,比方法1节省了1半的时间。如果大部分数据只有少数bit被置为1,那么效率的提升就更明显了。


虽然只是个小技巧,但是觉得还是挺有意思的。如果谁有更好的方法,也可以分享一下。






评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值