【C语言】求一个整数储存在内存中的二进制中1的个数

方法一:

举个例子,对“10”分析,它的二进制形式是1010

单纯对10本身分析,给10%2后看它能得到几个1,这也是一般十进制转化为二进制的过程:

我们进行代码实现:

这样一个简单的算法就写好了,可是仔细想想还是有地方有问题,int整形变量是有范围的,如果输入的值的范围超过的int整形变量的范围,比如我们输入一个负数,那程序就报错了,我们怎么解决这个问题呢,接下来看方法二从本质上分析。

方法二:

我们拿 -1 举例,-1在内存中的存储形式是-1的补码

10000000000000000000000000000001  ----  原码

1111111111111111111111111111111111110  ---- 反码

1111111111111111111111111111111111111  ---- 补码

我们把1的补码写出来

000000000000000000000000000000001

我们将1的补码与-1的补码进行按位与计算

得到0000000000000000000000000000001  = 1

这样就确认了 最后一位数字是1

然后我们在用>>移位操作符把-1的补码向右移动一位得到

01111111111111111111111111111111111111

我们在把这个补码与1的补码进行按位与计算得到

00000000000000000000000000000000001  = 1

这样我们又确认了-1的倒数第二位的数字是1

然后再往右位移  这样我们算法思路就出来了

接下来代码实现:

方法三:

还有没有更高级的算法呢,当然有,不过这种算法难以让人想到。

n = n & (n - 1)

举个例子

n(1) = 13  ----  1101

n(1)-1=12 ----  1100

n(2) = 1100

n(2) -1 = 1010

n(3)  = 1000

我们可以发现 每当进行这个算式一次,1都被消除一个,这样一个更高级的算法思路就出来了。

我们进行代码实现:

scanf函数这里的波浪线是编译器导致的,语句都没有错误,大家参考一下。

我所知道的方法大概就这些,以后发现更高级的算法会及时分享给大家的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值