【剑指Offer】二进制表示中1的个数

题目描述
输入一个整数,输出该数二进制表示中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;
     }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值