统计二进制中1的个数(C语言)

目录

题目概述

方法一

方法二

方法三


题目概述

给定一个整数n,写一个函数输出32位二进制表示中1的个数(负数用补码表示)

方法一

分析:当我们在计算1234的每一位数相加之和时,对于得到每一位数,我们的方法是用1234%10,得到4,再将1234/10,得到123,再用123%10,如此循环,直到1234变为0。

同理,对于得到整数的每一个二进制位,我们可以通过%2,/2的方式,得到该整数的每一个二进制位

代码如下

int NumberOf1(int n)
{
	int count = 0;
	while (n)
	{
		if (n % 2 == 1)
		{
			count++;
		}
		n /= 2;
	}
	return count;
}

测试

#include <stdio.h>

int NumberOf1(int n)
{
	int count = 0;
	while (n)
	{
		if (n % 2 == 1)
		{
			count++;
		}
		n /= 2;
	}
	return count;
}

int main()
{
	int n = 0;
	scanf("%d", &n);
	int ret = NumberOf1(n);
	printf("%d的二进制中1的个数为%d", n, ret);
	return 0;
}

测试结果

 

 然而,当输入的整数为负数时,结果就会出问题

 -1的补码为11111111111111111111111111111111

然而结果却为0,通过调试可以发现,当n为-1时,n%2的结果为-1,不等于1,count值不变,而-1/2的结果为0,此时循环退出。

 对于这种情况,我们可以使用unsigned int类型来接收n,将n转换为无符号的整数

int NumberOf1(unsigned int n)
{
	int count = 0;
	while (n)
	{
		if (n % 2 == 1)
		{
			count++;
		}
		n /= 2;
	}
	return count;
}

再次测试

此时结果正确

但是,对于这种方法,接收类型必须为unsigned int

方法二

若用n&1,则可以得到n的最后一位,再右移,移除已比较的位数,得到下一位,循环32次,得到二进制中每一位

代码如下

int NumberOf1(int n)
{
	int count = 0;
	for (int i = 0; i < 32; i++)
	{
		//将n向右移动i位,再&1
		if (((n >> i) & 1) == 1)
		{
			count++;
		}
	}
	return count;
}

测试

 

 但是,对于这种方法,要取出二进制中的每一位,则必须循环32次

方法三

当n&(n-1)时,能够去除n的二进制中最后一位1

例如

n = 10,二进制:1010

n - 1 二进制:1001

n&(n-1) = 1000

每一次n&(n-1),就去处二进制中一个1,则当n&(n-1)为0时,就去除了n中所有的1

代码如下

int NumberOf1(int n)
{
	int count = 0;
	while (n)
	{
		n = n & (n - 1);
		count++;
	}
	return count;
}

测试

 

  • 12
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 10
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

楠枬

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值