C语言,求一个十进制数的二进制中1出现的次数,版本2.0(另外两种方法介绍)

十进制的数字要分离十进制的每一位,要先模上10,获取个位数,接着除以十,将每一个位数都降低一级。再模上十,获取下一位数上的数字,再模上10......以此类推。

而二进制要获得每一位数,也是一样的。先模上2,获取第一位数,接着除以2,将位数降低。接着再模2,再除2......直到全部转化为二进制。

cpp 复制代码
#include <stdio.h>
int fun(int n)
{
	int count = 0;
	while (n)
	{
		if (n % 2 == 1)
		{
			count++;
		}
		n /= 2;
	}
	return count;
}
//这种方法不适用于负数
int main()
{
	int n = 0;
	scanf("%d", &n);
	int count = fun(n);
	printf("%d", count);
	return 0;
}

每一次循环判断到求得的相应位数为1(即n % 2 为1)时,count就会加一。

但是这种方法有一个缺点,如果n为负数,count的值就会为零,因为count在count++之后就会变成0,而0进入到循环的判断条件中,就会终止循环。

-1的补码应该是32个一,结果应该为32。

正确做法是将函数接收到的参数n转化为无符号整型,如此-1就不会因为二进制的第一位被函数解读为负数了。

如图:

cpp 复制代码
#include <stdio.h>
int fun(unsigned int n)
{
	int count = 0;
	while (n)
	{
		if (n % 2 == 1)
		{
			count++;
		}
		n /= 2;
	}
	return count;
}
//这种方法不适用于负数
int main()
{
	int n = 0;
	scanf("%d", &n);
	int count = fun(n);
	printf("%d", count);
	return 0;
}

用按位与&实现的方法在我之前的博客中写过了,但是无论是按位与的方法还是上面的方法,当n够大的时候,都要进行多次计算。

有没有一种方法能有多少个一就计算多少次呢,这种方法比较难想到,但是代码本身比较简单。

cpp 复制代码
#include <stdio.h>
int fun(int n)
{
	int count = 0;
	while (n)
	{
		n = n & (n - 1);
		count++;
	}

	//101011
	//101010
	//按位与 第一次
	//101010
	//101001
	//按位与 第二次
	//101000
	//100111
	//按位与 第三次
	//100000
	//000001
	//按位与 第四次
	//000000

	//结果为四
	return count;
}
int main()
{
	int n = 0;
	scanf("%d", &n);
	int count = fun(n);
	printf("%d", count);
	return 0;

这里利用里二进制逢二进一的特点,每当一位数是1后面位数都是0时,减去一就是让其位数变成0。再利用按位与的特点,只有位数都为一时,结果位数才为1。

相关推荐
越努力^越幸运13 分钟前
C中内存函数
c语言·开发语言
良木生香1 小时前
【数据结构-初阶】二叉树---链式存储
c语言·数据结构·c++·算法·蓝桥杯·深度优先
序属秋秋秋12 小时前
《Linux系统编程之进程控制》【进程等待】
linux·c语言·c++·进程·系统编程·进程控制·进程等待
lingran__14 小时前
C语言自定义类型详解 (1.1w字版)
c语言·开发语言
一路往蓝-Anbo18 小时前
C语言从句柄到对象 (一) —— 全局变量的噩梦与“多实例”的救赎
c语言·开发语言·stm32·单片机·嵌入式硬件·物联网
松涛和鸣18 小时前
DAY42 SQLite3 : Dictionary Import and Data Query Implementation with C Language
linux·c语言·数据库·单片机·网络协议·sqlite
水饺编程19 小时前
Visual Studio 软件操作:添加附加依赖项
c语言·c++·windows·visual studio
一路往蓝-Anbo20 小时前
C语言从句柄到对象 (三) —— 抛弃 Malloc:静态对象池与索引句柄的终极形态
c语言·开发语言·数据结构·stm32·单片机·算法
序属秋秋秋20 小时前
《Linux系统编程之进程控制》【进程创建 + 进程终止】
linux·c语言·c++·操作系统·进程·进程创建·进程终止
一路往蓝-Anbo20 小时前
C语言从句柄到对象 (二) —— 极致的封装:不透明指针与 SDK 级设计
c语言·开发语言·数据结构·stm32·单片机·嵌入式硬件