统计整数的二进制序列中1的个数 - C语言

文章详细介绍了如何使用C语言编写函数来统计有符号整数的二进制表示中1的数量。通过进制转换、按位与1以及按位与(num-1)三种方法,最终确定按位与(num-1)版本能有效处理正负整数的情况,避免了负数处理的错误。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

统计整数的二进制序列中1的个数 - C语言

我们知道,数据在内存中是以二进制的形式存储的,而整数的二进制的表示形式有三种:原码、反码、补码,在内存中整数以补码的形式存储。今天,我们就要编写C语言代码,统计一个整数在内存中的二进制序列中有多少个1。
在这里我们把这个功能封装成一个函数。而在函数具体实现之前,我们要创建一个函数环境,以检测函数运行结果。

函数环境

函数环境:

#include <stdio.h>
int number_of1(int );//函数声明
int main()
{
       int num = 0;
       scanf("%d", &num);
       int ret = number_of1(num);//函数调用
       printf("ret = %d\n", ret);//打印结果
       return 0;
}

函数环境创建完成后,我们就要开始实现函数了。

函数number_of1

注:示例为了简便,二进制序列均只写了4位。

版本1 - 进制转换版本

进制转换版本:
要点:十进制转换成二进制的原理。
示例:
进制转换

不完善版本

不完善版本:

int number_of1(int num)//版本1.0 - 进制转换 - 不完善版本
{
       int count = 0;
       while (num)//迭代
       {
              if (num % 2)
              {
                      count++;
              }
              num = num / 2;
       }
       return count;
}

我们发现当num为非负整数时,函数实现的很成功,但当num为负数时,结果就会发生错误,原因是负数的原码和补码并不相同。
解决方法:可以将函数形参改为无符号整型,将负数在内存中存放的补码当成无符号的进行计算,就是将负数的补码当成原码,转换成对应的正数,再进行迭代。

完善版本

完善版本:

int number_of1(unsigned int num)//版本1.1 - 进制转换版本 - 完善版本
{
       int count = 0;
       while (num)
       {
              if (num % 2)
              {
                      count++;
              }
              num = num / 2;
       }
       return count;
}

但是我们会发现,在声明函数时,函数的形参我们希望的是int类型,而进制转换的完善版本的函数形参与声明不同,所以我们要进一步思考还有什么方法可以实现该函数功能呢。
接下来就是我们的第二个版本,按位与1版本。

版本2 - 按位与1版本

按位与1版本:
示例:
按位与1

int number_of1(int num)//版本2 - 按位与1版本
{
       int count = 0;
       while (num)//迭代
       {
              if (num & 1)
              {
                      count++;
              }
              num = num >> 1;
       }
       return count;
}

但是我们很快发现,右移分为算术右移和逻辑右移两种,不同编译器可能不同,导致负数在算术右移的情况下左边补1,会陷入死循环,所以这个版本依然不能很好符合我们的要求,所以我们要继续思考其他版本。
注:此版本函数形参改为unsigned int可以实现函数功能,原理大致同进制转换中提到的差不多,这里不重新介绍,但修改后仍与函数声明时的函数形参不同。

版本3 - 按位与(num-1)版本

按位与(num-1)版本:
示例:
按位与num-1

int number_of1(int num)//版本3 - 按位与(num-1)版本
{
       int count = 0;
       while (num)
       {
              count++;
              num = (num & (num - 1));
       }
       return count;
}

经过运行调试,我们发现版本3很好的实现了统计有符号整数的二进制序列中1的个数。
版本3的运行结果:
num = 13
num=13

num = -1
num=-1

经过一番努力,我们终于实现了统计整数二进制序列中1的个数的函数!

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值