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

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

内容:

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

比如: 150000   1111  4个1

方法1:

//统计二进制中1的个数
#include<stdio.h>
int count_num_of_1(int n)
{
	int count = 0;
	while (n)//n如果不是0,说明它的二进制位一定有1
	{
		if ((n % 2) == 1)
		{
			count++;
		}
		n /= 2;
	}
	return count;
}
int main()
{
	int num = 0;
	scanf("%d", &num);
	int n = count_num_of_1(num);
	printf("%d\n", n);

	return 0;
}

以上代码一个小问题,当num是正数的时候,它能计算的结果是正确的;但是当num是负数时,它计算的结果是错误的。

那为什么会出现以上结果呢?

  改进方式:

//统计二进制中1的个数
#include<stdio.h>
//int count_num_of_1(int n)
int count_num_of_1(unsigned int n)
{
	int count = 0;
	while (n)
	{
		if ((n % 2) == 1)
		{
			count++;
		}
		n /= 2;
	}
	return count;
}
//-1
//10000000 00000000 00000000 00000001 原码
//11111111 11111111 11111111 11111110 反码
//11111111 11111111 11111111 11111111 补码
// 如果将(11111111 11111111 11111111 11111111)放到无符号数里面,
// 那么编译器就会认为第一个1不再是符号位,而是一个很大的正数
//num=-1时,计算的结果应该是32
 
int main()
{
	int num = 0;
	scanf("%d", &num);
	int n = count_num_of_1(num);
	printf("%d\n", n);

	return 0;
}

 

方法2:

要想得到一个数的二进制位中1的个数,可以将二进制位数一个一个拿出来,再判断它是否为1.

#include<stdio.h>
int count_num_of_1(int n)
{
	int i = 0;
	int count = 0;
	for (i = 0; i < 32; i++)
	{
		if ((n >> i) & 1 == 1)
		{
			count++;
		}
	}
	return count;
}
int main()
{
	int num = 0;
	scanf("%d", &num);
	int n = count_num_of_1(num);
	printf("%d\n", n);

	return 0;
}

方法3:

以上两种方法效率都不够高。

#include<stdio.h>
int count_num_of_1(int n)
{
	int count = 0;
	while (n)
	{
		n = n & (n - 1);
		count++;
	}
	return count;
}
int main()
{
	int num = 0;
	scanf("%d", &num);
	int n = count_num_of_1(num);
	printf("%d\n", n);

	return 0;
}

2.判断一个数是不是2的次方

#include<stdio.h>
int Is_num(int n)
{
	if ((n & (n - 1)) == 0)//因为(n & (n - 1)这个表达式每执行一次,就会去掉一个1
		return 1;
	else
		return 0;
}
int main()
{
	int num = 0;
	scanf("%d", &num);
	int flag = Is_num(num);//如果是则返回1,不是则返回0
	if (flag == 1)
		printf("%d是2的次方\n", num);
	else
		printf("%d不是2的次方\n", num);
	return 0;
}

 

3.求两个数二进制中不同位的个数

作业内容

编程实现:两个int(32位)整数m和n的二进制表达中,有多少个位(bit)不同? 

输入例子:

1999  2299

输出例子:7

方法1:

#include<stdio.h>
int count_diff_bit(int m, int n)
{
	int i = 0;
	int count = 0;
	for (i = 0; i < 32; i++)
	{
		if (((m >> i) & 1) != ((n >> i) & 1))
		{
			count++;
		}
	}
	return count;
}
int main()
{
	int m = 0;
	int n = 0;
	scanf("%d %d", &m, &n);
	int ret = count_diff_bit(m, n);
	printf("ret=%d\n", ret);
	return 0;
}

方法2:

^ 异或操作符——相同为0,相异为1。所以只需要统计m^n中二进制数中有几个1,就是m和nn的二进制表达式中,有多少个位(bit)不同?

#include<stdio.h>
int count_diff_bit(int m, int n)
{
	int count = 0;
	int ret = m ^ n;
	while (ret)
	{
		ret = ret & (ret - 1);
		count++;
	}
	return count;
}
int main()
{
	int m = 0;
	int n = 0;
	scanf("%d %d", &m, &n);
	int ret = count_diff_bit(m, n);
	printf("ret=%d\n", ret);
	return 0;
}

 

4.打印整数二进制的奇数位和偶数位

作业内容

获取一个整数二进制序列中所有的偶数位和奇数位,分别打印出二进制序列。

//获取一个整数二进制序列中所有的偶数位和奇数位,分别打印出二进制序列
//00000000 00000000 00000000 00001010 - 认为最左边的为第一位
#include<stdio.h>
int main()
{
	int i = 0;
	int num = 0;
	scanf("%d", &num);
	//获取奇数位数字
	for (i = 30; i >= 0; i -= 2)
	{
		printf("%d ", (num >> i) & 1);
	}
	printf("\n");
	//获取奇数位数字
	for (i = 31; i >= 1; i -= 2)
	{
		printf("%d ", (num >> i) & 1);
	}

	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值