如何计算数字所代表的二进制个数

注意:

光看解释可能会很晕,最好看代码思考,加以解释进行理解

方法一

由二进制的性质可知 

二进制任何位置的1 不断除以2  该位置的1会不断右移 直到移到第一位

第一位的1又不能被2整除 会余下1

方法二

理解完方法一后 可以明白

不过就是将二进制高位的1 右移 直到第一位 再计算1的个数(count++)

但是越高位的数字1 除以2 的操作次数越多(二进制性质)

是不是太麻烦了?我们能不能更高效一点?

我们其实也可以将第一位的1左移 来进行比较,

怎么操作呢? 我们要知道&和<<操作符的性质再看以下代码

int类型32位比特

000000000 00000000 00000000 00000001

补充:每次左移时 右边自动补0

如果两数取&后不为0 则必须是两数的二进制上的相同位置都为1

此时count++也是变相的计算了二进制中1的次数

方法三

虽然方法二的效率更稳定,因为它只需要固定循环32次 就可以计算出结果

但还有更快的方法吗?

我们可以从另一个角度出发------异同

因为计算机中的二进制只有0和1

要是我所求的数的二进制数字不断转化为相同的数字(0) 一次消除一个不同,count++

最后所有数相同时(数值变为0)跳出循环即可

此时只需将该   数-1  导致 二进制数中的1右移一位  or   第一位的1变成0

此时再该      数&(数-1)相当于同化了一个二进制中的1变为0 

【减1  是先将二进制数中 低位的1先右移 再减1时相对较高位的1右移

  所以 右移时 转移位置的值肯定为0(理解)】

所以&后只会改变一个值

(右移后的转移位置本就是0,&后还是0,而右移后原本位置为0,肯定会被同化为0)

最好还是一边看代码一边看解析容易理解

以上就是全部内容,如果有瑕疵,欢迎纠正
  

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值