写一个函数返回参数二进制中1的个数

目录

如何得出二进制的每一位?

写一个函数返回参数二进制中1的个数

方法一(常规)

完善

方法二(位操作符) 

方法三(位操作符 - 进阶)


如何得出二进制的每一位?

在思考之前,回忆如何得出十进制中的每一位?

如:1234

1234 % 10 = 4

1234 / 10 = 123

-----

123 % 10 = 3

123 / 10 = 12

-----

12 % 10 = 2

12 / 10 = 1

-----

1 % 10 = 1

1 / 10 = 0

同理:

二进制的每一位可以通过 %2 和 /2 得到 

如:11

11 % 2 = 1

11 / 2 = 5

-----

5 %2 = 1

5 / 2 = 2

-----

2 % 2 = 0

2 / 2 = 1

-----

1 % 2 = 1

1 / 2 = 0

所以11的二进制位:1101


写一个函数返回参数二进制中1的个数

方法一(常规)

#include <stdio.h>

int count_num_of_1(int num)
{
	int count = 0;//用来记录1的个数

	while (num) 
	{
		if ((num % 2) == 1)
		{
			count++;
		}
		num /= 2;

	}
	return count;
}

int main()
{
	int num = 0;
	scanf("%d", &num);

	int ret = count_num_of_1(num);
	printf("%d", ret);


	return 0;
}

当输入-1时,结果为0

-1

补码:11111111111111111111111111111111

所以,-1的二进制中应该有32个1

但在代码中,-1进入函数

-1 % 2 = -1

-1 / 2 = 0

最后num = 0,循环停止

完善

int count_num_of_1(unsigned int num)

 只需传数时,传入无符号数,那么就会将-1的11111111111111111111111111111111看作是非常大的正数

结果为32

方法二(位操作符) 

位操作符 按位与 & - 全1是1

#include <stdio.h>

int count_num_of_1( int num)
{
	int i = 0;
	int count = 0;
	for (i = 0; i < 32; i++)
	{
		if (((num >> i) & 1) == 1)
		{
			count++;
		}
	}
	return count;
}

int main()
{
	int num = 0;
	scanf("%d", &num);

	int ret = count_num_of_1(num);
	printf("%d", ret);

	return 0;
}

思路:

通过数字的补码的右移 i 位,遍历了所有的二进制位

然后&1,看最后1个二进制位是否为1

这个代码对给出的正负数,都可以计算二进制中的1的个数

方法三(位操作符 - 进阶)

num = num & (num -1)

执行1次,去掉一个1

如:num = 15

1111 num

1110 num - 1

-----

1110 num

1101 num - 1

-----

1100 num

1011 num - 1

-----

1000 num

0111 num - 1

-----

0000 num

#include <stdio.h>

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

int main()
{
	int num = 0;
	scanf("%d", &num);

	int ret = count_num_of_1(num);
	printf("%d", ret);

	return 0;
}

 思路:

num = num & (num - 1)

每次二进制位最右边的数变成0,后面的0借位变成1,这样才是-1

比如:1100(2² + 2³ = 12)

变成:1011(2⁰ + 2¹ + 2³ = 11)

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值