题目:求二进制中1的个数
输入一个整数,输出该数二进制表示中1的个数。其中负数用补码表示。
0、前言
此题考查二进制的位运算。
一般情况下,负数的二进制表示以其正数的补码形式表示。
原 码
一个整数按照绝对值大小转化成的二进制数称为原码
例如:00000000 00000000 00000000 00001110 是14的原码。
反 码
将二进制数按位取反,所得到的新二进制数称为原二进制数的反码。
例如:将00000000 00000000 00000000 00001110 每一位取反,
得11111111 11111111 11111111 11110001
注意:这两者互为反码
补 码
反码加1称为补码,也就是-14的二进制表示。
11111111 11111111 11111111 11110001 +1=
11111111 11111111 11111111 11110010
参考学习链接:Java 位运算(移位、位与、或、异或、非)
1、题目解法
思路见注释。
方法一
/**
* 思路:某个数n-1的二进制表示,其实是n的二进制表示里面的最后一个1及以后的数都改变。
* 比如5(101);4(100)。
* 所以说n&(n-1)就可以把n的最后一个1变成0。(自己动手看一看,的确如此)
* 所以说做几次这样的运算就有几个1,直到n变成0。
* @param n
* @return
*/
private int test01(int n) {
int count = 0;
while (n != 0) {
count++;
n = n & (n - 1);
}
System.out.println("1的个数有" + count + "个");
return count;
}
方法二
/**
* 定义一个指针flag从1开始。只要flag不为0,将n与flag取&运算,
* 如果不等于0,说明n中该位为1,count++。flag左移一位。
* 这种思路相当于把指针不断左移,与每一位进行比较。
* @param n
* @return
*/
private int test02(int n) {
int count = 0;
int flag = 1;
while (flag != 0) {
if ((n & flag) != 0)
count += 1;
flag = flag << 1;//flag左移
}
System.out.println("1的个数有" + count + "个");
System.out.println(Integer.toBinaryString(-14));
return count;
}