【剑指offer刷题】11--按位与--二进制中1的个数

输入一个整数,输出该数二进制表示中1的个数。其中负数用补码表示。

简单说明知识点:

1.原码、反码、补码

数字在计算机中是以特定的编码方式存储的,在这里以正数 +1 和负数 -1为例,以8位二进制存储。

原码:+1:0000  0001     -1:1000 0001  符号位加上真值的绝对值,第一位是符号位,0表示正数,1表示负数

反码:+1:  0000  0001      -1:1111 1110  正数的反码==原码,负数的反码==原码的符号位不变,其余位取反

补码:+1:  0000  0001      -1:1111 1111  正数的补码==原码,负数的补码==原码的符号位不变,其余位取反,再+1

 +1-1
原码0000  00011000 0001
反码0000  00011111 1110
补码0000  0001 

2.左移<< 和 右移 >>

有符号的左移 <<n, 扩大2^n倍

有符号的右移 >>n,缩小2^n倍,   例子  4>>2 

4: 0000 0100   右移两位   0000 01

例子  -4>>2 ,最高位补1 

-4: 1111 1100    右移两位   1111 1111

 

本题中注意输入的整数可能是正数  负数   零,负数在右移时,最高位补1。第一种思路可将整数转为无符号整数,再按照正数的处理方法即可。

第二种思路:先举个例子,一个二进制数1100,从右边数起第三位是处于最右边的一个1。减去1后,第三位变成0,它后面的两位0变成了1,而前面的1保持不变,因此得到的结果是1011.我们发现减1的结果是把最右边的一个1开始的所有位都取反了。这个时候如果我们再把原来的整数和减去1之后的结果做与运算,从原来整数最右边一个1那一位开始所有位都会变成0。如1100&1011=1000.也就是说,把一个整数减去1,再和原整数做与运算,会把该整数最右边一个1变成0.那么一个整数的二进制有多少个1,就可以进行多少次这样的操作。

 

解1:

// solution 1:
    int NumberOf1(int n)
    {
        if(n==0)
            return 0;
        unsigned int num=(unsigned int)n;
        int count=0;
        while(num!=0){
            if(num&1==1)
                count++;
            num>>=1;
        }
        return count;
    }

解2:

// solution 2:
int NumberOf1(int n)
{
	if(n==0)
		return 0;
	int count=0;
	while(n!=0){
		count++;
		n=n&(n-1);
	}
	return count;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值