文章目录
求一个数的二进制表示形式中有多少个1
举个例子:
12转化为二进制是1100,1100中有2个1
对于任意一个数(要在INT_MIN和INT_MAX之间),求它的二进制表示形式中有多少个1,有下面几种方法
1.模2然后在除2
例如a=12
 a=12-------- ①a%2=0-------- a/2=6-------- a=6(将a/2的结果在赋给a)
 a=6 --------- ②a%2=0-------- a/2=3-------- a=3
 a=3---------- ③a%2=1-------- a/2=1-------- a=1
 a=1-----------④a%2=1---------a/2=0---------a=0
 对a%2从④~①进行排序,得到的就是1100,是12的二进制序列
 产生这种情况的原因可以类比于一个十进制数模10除10
 例如,对于十进制数123
 123%10=3--------123/10=12
 12%10=2----------12/10=1
 1%10=1-----------1/10=0
 可以得到1,2,3
 于是,可以利用这个原理去求一个数的二进制表示形式中1的个数
代码如下
#include<stdio.h>
#pragma warning(disable:4996)
int Tobinary(int n)
{
	int count = 0;//创建一个计数器
	while (n)//n=0,跳出循环
	{
		if (1 == n % 2)
		{
			count++;
		}
		n /= 2;
	}
	return count;
}
int main()
{
	int a = 0;
	printf("输入想要进行操作的数\n");
	scanf("%d",&a);
	int ret=Tobinary(a);
	printf("%d\n",ret);
	return 0;
}
但是这种方法不能操作负数,下面介绍可以操作负数的方法
2.a&1
例如
 a=7
 二进制为111
 int a=-1,a在内存中的存储就是
 11111111 11111111 11111111 11111111(补码)
 a&1
 11111111 11111111 11111111 11111111
 00000000 00000000 00000000 00000001
 00000000 00000000 00000000 00000001
 a&1=0,则a最后一位一定是0,a&1=1,则a最后一位一定是1。然后将a右移一位(逻辑右移),再次按位与1
 *这种方法仅适用于逻辑右移的机器
 因为逻辑右移是补0,而算数右移是补原符号位
 代码如下
#include<stdio.h>
#pragma warning(disable:4996)
int Tobinary(int n)
{
	int count = 0;//创建一个计数器
	while (n)//n=0,跳出循环
	{
		if (n&1)
		{
			count++;
		}
		n >>= 1;
	}
	return count;
}
int main()
{
	int a = -1;
	int ret=Tobinary(a);
	printf("%d\n",ret);
	return 0;
}
3.a&(a-1)
这个方法适用于正数和负数,并且不用考虑算数右移和逻辑右移的问题
 例如
 a=11
 a:1011
 a-1:1010
 a&(a-1)=1010
 将a&(a-1)的值在赋给a
 a:1010
 a-1:1001
 a&(a-1)=1000
 以此类推,每一次a&(a-1),得到的二进制数中1的个数总是比原来的a少一个
 可以利用这个原理求1的个数
#include<stdio.h>
#pragma warning(disable:4996)
int Tobinary(int n)
{
	int count = 0;
	while (n)//n=0,跳出循环
	{
		n &= n - 1;
		count++;
	}
	return count;
}
int main()
{
	int a = 2396;
	int ret=Tobinary(a);
	printf("%d\n",ret);
	return 0;
}
4.递归
递归方法不需要计数器
 对于正数,左移一位不改变二进制表示形式中1的个数
 对于负数,左移一位二进制表示形式中1的个数减少一位
#include<stdio.h>
#pragma warning(disable:4996)
int Tobinary(int n)
{
	if (n>0)
	{
		return Tobinary(n<<1);
	}
	else if (n<0)
	{
		return Tobinary(n << 1) + 1;
	}
	else
	{
		return 0;
	}
}
int main()
{
	int a = 2396;
	int ret=Tobinary(a);
	printf("%d\n",ret);
	return 0;
}










