方法一:
判断一个数的二进制共有几个1,无非就是把每个二进制位都拿出来看是不是1,是1计数器就+1
我们可以联想到:要获取到十进制123的每一位可以采用123%10得到3,123/10得到12;循环往复的执行%10、/10操作就可以得到123的每一位
同理,要获取到一个数的二进制每一位,那么只要这个数不为0,循环执行%2、/2操作就可以得到
代码:
13的二进制是1101,有三个1没问题。可当你判断-1的二进制有几个1时结果是0,因为这个程序只能针对正整数
负数怎么办?
方法二:
在方法一中我们无法判断负数,既然这样那就不管正负二进制位都循环32次,把这个数的二进制每一位拿出来看是不是1,是计数器+1
为什么是32?
因为一个整型是4个字节,1个字节是8个比特位,所以1个整型是4*8=32个比特位
按位与&和右移>>操作符
按位与&:只对二进制进行操作,对应二进制位相与,有0则0,两个相同为1则为1
右移>>:只对二进制进行操作,分为算术右移和逻辑右移
算术右移:右边抛弃,左边补符号位(大部分编译器使用)
逻辑右移:右边抛弃,左边补0
举个栗子:
13的二进制表示:
要想获取到最后一位,可以&上一个1(有0则0,两个相同为1则为1)
每次先右移1次(这样32个位都可来到最后一位)再给13按位与1,若13最后一位是1为1,不是的话为0,这样循环32次就可判断13的二进制中最后一位是不是1
不可以右移后不&1,如果不&1只右移就改变了原数值13
代码:
有没有更优化的算法? 有
方法三:
用n =n&(n-1),此方法不需要循环32次,该数的二进制有几个1就循环几次,所以进入循环的次数为1的个数
13的二进制是1101,(n-1)为1100,这两个按位与得1100,将新的n与之前的n相比,可以发现每次n最右边的1都会消失,所以按位与一次会消失个1,二进制位有多少个1就执行n =n&(n-1)多少次,直到整个二进制全为0
为什么会出现按位与1次消失一个1?
其实观察一组n和(n-1)不难发现,每次(n-1)都出现位数不够减1向前借1情况,这样原本n最左边1的那位数通过(n-1)会变为0;不管其后面是1还是0,按位与都不影响,都是0
代码: