浅谈整型数据补码中1个数的计算

我们该如何计算整型数据补码,即相应二进制中1的个数呢?

1、商余法

这是我自己取的名字,顾名思义,这种算法要用到/和%。

对于十进制而言,我们要拿到每一位上的数,最简单的方法就是除10、模10。其实二进制也是一样的,只不过改成除2和模2。

这种方法的思路在于:拿到每一位上的数,然后与1进行比较,等于1,计数变量便加1,直到所求整型数据在不断的除2中变为0为止。

但这样写的话对负整数就不适用了。要想求出负整数的补码中1的个数,我们想着,要是能把负整数的补码直接拿出来就好了,像运算正整数一样,运算负整数的补码,这该怎么实现呢?

实现方法非常简单,但也异常巧妙:将函数形参的类型改为unsigned int。这样,在计算机内存中,当实参的补码传递给形参时,会自动算术转换为无符号数。在这样的情况下,如果实参是负数,那么形参将会是二进制大小等于实参补码的一个无符号数,或者说理解为正整数。如此,我们成功地将负整数的补码拿出。

可见,代码修改过后,对于负整数也能很好地适用。

2、右移操作和按位与

这种方法其实也是拿出补码中的每一位与1进行比较,不过是通过位操作符实现的。

将一个数按位与1,可以得到其第一个二进制位上的数;而若想得到其第二个二进位上的数,可以将此数右移一个单位,然后再按位与1,这样便可得到原数第二个二进制位上的数,以此类推。

所以,代码实现如下:

3、按位与

以上两种方法其实都不够简洁,存在一定时间的浪费,因为这两种方法是把补码中每一位都拿出来进行比较,而不是所有数补码中的每一位均为1.

那么,有没有一种方法是直接统计整型数据补码中1的个数呢?

这是我们还是要用到按位与&操作符,具体代码如下所示:

这是什么意思呢?

举个例子:

现在有一个二进制数:1111。

第一次按位与:1111&1110 = 1110

第二次按位与:   1110&1101 = 1100

第三次按位与:   1100&1001 = 1000

第四次按位与: 1000&0111 = 0000

看完上面这个例子,肯定就明白了:a&(a-1) 就是将a的二进制补码中最右边的一个1改为0。既然如此,我们不断的对a进行这样按位与的操作,最后就能将a的补码中,所有为1的位都变成0,此时a的值也就变成了0。而进行一次这样的操作,a的补码中最右边的一个1就变为0,计数变量便加1用以记录。

这种方法只单纯统计了补码中1的个数,而略去了补码中为0的位,显然效率更高。

可以看到,此种算法的输出结果也是没有问题的。

  • 6
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值