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

统计一个数二进制中1的个数

方法一

对求值对象先模2后除以2,直到其值为0,这个方法与"除2取余,逆序排列"进行十二进制转换的相同。缺点是这个方法有取模运算,所以只能统计正数,不适用于负数的统计。

u_int countOne1(int num)
{
	u_int count = 0;
	while (num)
	{
		if (num % 2==1){
			count++;
		}
		num /= 2;
	}
	return count;
}

方法二

让该数和1>>31相与,判断最高位为1或者0,然后对该数进行左移,重复上面步骤,直到统计完32个比特位。这种方法无论求值对象有多少个1,循环都要执行32次,程序效率低。
在这里插入图片描述

u_int countOne2(int num)
{
	u_int count = 0;
	int flag = 1 << 31;
	for (int i = 0; i < 32; i++)
	{
		if ((num<<i)&flag){
			count++;
		}
	}
	return count;
}

方法三

逐个消去最后一位的1,如下图,根据两个数相与的规律可以知道,一个数字的二进制序列和它本身的二进制序列-1相与,就会将该数最低的有1的比特位清成0。这种放法的好处是,二进制序列中有几个1循环就执行几次,程序效率高。
在这里插入图片描述

u_int countOne3(int num)
{
	u_int count = 0;
	while (num)
	{
		num&=num - 1;
		count++;
	}
	return count;
}

完整代码

#include<stdio.h>
#include<windows.h>
#define unsigned int u_int

//方法一:模2除2
u_int countOne1(int num)
{
	u_int count = 0;
	while (num)
	{
		if (num % 2==1){
			count++;
		}
		num /= 2;
	}
	return count;
}

//方法二:位运算
u_int countOne2(int num)
{
	u_int count = 0;
	int flag = 1 << 31;
	for (int i = 0; i < 32; i++)
	{
		if ((num<<i)&flag){
			count++;
		}
	}
	return count;
}

//方法三:逐个消去最后一位的1
u_int countOne3(int num)
{
	u_int count = 0;
	while (num)
	{
		num&=num - 1;
		count++;
	}
	return count;
}

int main()
{
	int a = 1023;
	u_int x = countOne1(a);
	u_int y = countOne2(a);
	u_int z = countOne3(a);

	printf("%d %d %d\n", x,y,z);
	system("pause");
	return 0;
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值