题目描述
输入一个整数,输出该数二进制表示中1的个数。其中负数用补码表示。
错误解法:
第一反应写的代码输出错误,没有考虑到负数补码的情况。
class Solution {
public:
int NumberOf1(int n) {
int ans=0;
while(n>0){
if(n%2==1)
ans++;
n=n>>1;
}
return ans;
}
};
正确解法1:
用1不断左移运算,与N进行&操作。
class Solution {
public:
int NumberOf1(int n) {
int ans=0;
int tmp=1;
while(tmp!=0){ //这里tmp最终的值为0000000000000
if((n&tmp)!=0)
ans++;
tmp=tmp<<1;
}
return ans;
}
};
注意 -2147483648:
64位系统中,int的最小值为-2147483648 = -2^31,其补码为1000…0000。计算时采用补码。
那对-2147483648取负值时,按理论应该是2147483648,但超过int能表达的最大正值,相当于2147283647+1=0111…1111+0000…0001=1000…0000=-2147483648(按补码理解)。也就是说对-2147483648取负仍然是-2147483648。
对-2147483648-1时,相当于1000…0000+1111…1111(-1的补码)=0111…1111(溢出后)=2147483647(int的最大正值)
正确解法2:
这种做法n&(n-1) 每次去掉最右边的一个1 。
class Solution {
public:
int NumberOf1(int n) {
int ans=0;
while(n!=0){
ans++;
n=n&(n-1);
}
return ans;
}
};