JDK中Integer.bitCount解析

使用过Redis的人可能知道,Redis中给我们提供了统计二进制位数为1的位数量的指令bitcount,JDK中Integer类同样也给我们提供了该功能的方法Integer.bigCount,得益于此,我们很容易就能一窥该方法的实现

    public static int bitCount(int i) {
        // HD, Figure 5-2
        i = i - ((i >>> 1) & 0x55555555);
        i = (i & 0x33333333) + ((i >>> 2) & 0x33333333);
        i = (i + (i >>> 4)) & 0x0f0f0f0f;
        i = i + (i >>> 8);
        i = i + (i >>> 16);
        return i & 0x3f;
    }

上述代码作为Integer类中比较有意思的一个方法,该方法利用了一个技巧:通过分割分配二进制位的方式,CPU可以实现一个指令同时计算多个数值。该方法的前四行都利用了该技巧。

NOTE:CPU要通过分配字节位的方式同时计算多个数值对,需要有一定的前提:由于每个数分配的字节位的长度有限,这就要求计算结果的二进制表示不能超出分配的位数。在当前问题上,显而易见是成立的:相加的两个数的最大值所占的二进制位数只有分配的二进制位的一半,结果值需要的二进制位必然不会超过分配的二进制位数。

案例解析

为了利于问题的解决,对计算二进制位1的数量这个问题,做一个等价转换:计算二进制位上每一位值的和。

以数字‭1823425321‬为例,二进制数值为

‭0 1 1 0  1 1 0 0  1 0 1 0  1 1 1 1  0 1 0 0  0 0 1 1  0 0 1 0  1 0 0 1‬

1. 方法第一行

将二进制的每1位都视为一个单独的数字,从左往右两个两个数字配对,形成16组二进制数相加,得到16个数值(2位二进制)。为了使结果是2位二进制数,相加前还需先给每个数前面补零。计算过程如下:

‭0 1  1 0  1 1  0 0  1 0  1 0  1 1  1 1  0 1  0 0  0 0  1 1  0 0  1 0  1 0  0 1‬     
                                      ⇩  
00   01   01   00   01   01   01   01   00   00   00   01   00   01
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值