题目描述
输入一个整数,输出该数二进制表示中1的个数。其中负数用补码表示。
思路:
1. 由于计算机存储数据是用2进制,所以可以想到用位移的方式。(得补基础了同学们!!)
学过硬件写过cpu指令或者玩过单片机FPGA的电子系同学可能比较熟悉位移。(虽然我们大学也学过,但我太菜已经忘差不多了)
2. 首先,得清楚整数是int类型,计算机中占4字节,32bit。(1byte=8bit)
(java中有8种基本类型:byte:占1字节,short:占2字节,int 占4字节,long占8字节,float占4字节,double占8字节,char占2字节,boolean占1字节)
补码概念:
计算机中用0,1表示任何数字,有符号数的话,前面高位为0,表示正数;高位为1,表示负数。
所以负数在计算机中用补码表示。 补码即将原来正数形式的二进制数,取反再加一,如:
1的整数二进制在计算机中存储情况为:00000000 00000000 00000000 00000001
-1在计算机中存储情况为:11111111 11111111 11111111 11111111
(为什么是这样?首先对整数1进行取反,变为:11111111 11111111 11111111 11111110,
再加一:变为:11111111 11111111 11111111 11111111)
还是不懂补码的话,自行google或百度哈。
计算机中存负数就是按照补码的形式,所以位运算可以不用管它,一同操作就行。
public int NumberOf1(int n) {
int count = 0; //计数器count存储最后结果:二进制中1的个数
//因为int有32位,要将每一位都移过来跟1进行“按位与运算”
//结果还是1的话,说明这个二进制就是1,计数器count加一
for(int i=31;i>=0;i--){
int bit =(n>>i)&1;
if(bit == 1){
count++;
}
}
return count;
}
方法二:
public static int num(int i){
int count = 0;
int flag = 1;
while(flag != 0){
if((i & flag) != 0){
count++;
}
flag = flag << 1;
}
return count;
}
方法三:
其他解决方法参考: