注意:
光看解释可能会很晕,最好看代码思考,加以解释进行理解
方法一
由二进制的性质可知
二进制任何位置的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)
最好还是一边看代码一边看解析容易理解
以上就是全部内容,如果有瑕疵,欢迎纠正