c语言:写一个函数求a的二进制(补码)表示中有几个1

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>

int main()
{
	int a = 0;
	scanf("%d", &a);
	int count = count_bit_one(a);
	printf("count = %d\n", count);
	return 0;
}

算法一(类比十进制的%10得到最后一位数字,再/10去掉最后一位数字):

int count_bit_one(int a)
{
	int count=0;//计数器
	while (a)//a=0时跳出循环
	{
		if (a % 2 == 1)
			count++;
		a = a / 2;
	}
	return count;
}

缺点:如果a是负数,则a会跳出循环,比如 - 1/2=0;

优化:把a定义成无符号数,除去二进制中符号位对结果的影响

int count_bit_one(unsigned int a)
{
	int count=0;//计数器
	while (a)//a=0时跳出循环
	{
		if (a % 2 == 1)
			count++;
		a = a / 2;
	}
	return count;
}

算法二:按位与判断二进制每一位,再用移位操作符

int count_bit_one(int a)
{
	int count = 0;
	int i = 0;
	for (i = 0; i < 32; i++)
	{
		if (((a >> i) & 1) == 1)//位操作符(用于二进制),按位与
			count++;
	}
	return count;
}

更优:算法三:

我们先来看 n=n&(n-1)这个算法

假如一开始n等于13

二进制

1101        n

1100        n-1(12)

1100        n

1011        n-1(11)

1000        n

0111        n-1(8)

0000        n

结论:我们观察每个n,发现每次经过一轮n&(n-1)运算之后的n,二进制位最低位都可以消除一个1,二进制都减少了一个1。最后到全为0,经过了多少轮,就有多少个1

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

总结:前两种方法相似,都要将整个32个比特位都比较完,比较浪费时间和空间,而这个算法二进制有多少个1就计算多少次。

编程小白,如有问题,请多指教Thanks♪(・ω・)ノ

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值