全网最易懂的解题——C语言“求一个整数在内存中的二进制中1的个数”

所以这题要怎么做呢,整数在内存中是以二进制形式存放的,所以我们先要把这个数转化成二进制形式吧

同样我们也可以通过这种方法去得到 二进制 的每一位

//结论:此代码不对负数有效
int main()
{
	int num = 13;
	int count = 0;
	while (num)
	{
		if (num % 2 == 1)
		{
			count++;
		}
		num /= 2;
	}
	return 0;
}

 

代码到这就写完了吗,那如果是负数呢,num = -1的时候输出结果是0,这不是我们想得到的

 优化思路:

按位与1,代表了除了最后一位,其他位永远不可能是1。所以我们就可以做到一直去比较最后一位。那比较完了最后一位,我们只要将补码向右移动一位继续比较就行了

    //num向右移动1位,最左边用0补齐
    num>>1;

这种方法的好处就是,代码对比的直接就是num在系统中的补码,因为num就是以补码的形式储存于内存中

//求一个数它的二进制位有几个1
int main()
{
	int num = -1;
	int count = 0;
	
	for (int i = 0; i < 32; i++)//数字存在内存中有32位,比较32次
	{
		if ((num >> i) & 1 == 1)//每次比较用右移i位
		{
			count++;
		}
	}
	printf("%d", count);

	return 0;
}

更为巧妙的思路:

这个方法每次都能让n最右边的1消失,因为有1的时候让1消失,没1的时候向前面借位。

通过执行表达式,n最终会为0,那在n变成0之前执行了几次,就是把几个1消失。

//求一个数它的二进制位有几个1
int main()
{
	int n = -1;
	int count = 0;
	
	while (n)
	{
		n = n & (n - 1);
		count++;
	}

	printf("%d",count);

	return 0;
}

有帮助到你是我的荣幸,赏个赞吧~

  • 17
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值