Integer.bitCount()解析

平常刷算法题的时候计算一个数二进制有多少个1的时候一般我都这么写

int count = 0;
while(x!=0){
    x &= x-1;
    count++;
}

今天特意去看了下自带的Integer.bitCount(),发现其实现还挺有意思,特此记录

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;
}

其思想就是:要计算32位中有多少个1,先2个一组,总共分成16组,计算每组的两位中有几个1,然后再每两组把结果相加,得到每4个一组,每组有多少个1,以此类推,最后得到总共有多少个1.

首先来看每2个一组如何得到1的个数:

二进制数个数
00

0

01

1

101
112

无非就是以上4种情况,可以得出一个结论:1的个数 = 二进制数 - (( 二进制数 >>1 ) & 1)。

按照这个结论,第一行 i = i - ((i >>> 1) & 0x55555555); 也就不难理解,0x55555555是十六进制,写成二进制是01010101010101010101010101010101,相当于分成每两个一组,每组的结果即是1的个数,其中 >>> 是无符号右移。

第二行 i = (i & 0x33333333) + ((i >>> 2) & 0x33333333) 是相当于把刚才分好的结果每两个进行合并,0x33333333即00110011001100110011001100110011,i & 0x33333333相当于,(i >>> 2) & 0x33333333是取高两位。

经过前两行,现在的结果相当于是每4个数位一组,一共8组,每组保存着原来该4位1的数量。再来看第3行,i = (i + (i >>> 4)) & 0x0f0f0f0f,0x0f0f0f0f是00001111000011110000111100001111,这里的结果是每8个数位一组,每组保存着原8个数位1的数量,有一点注意一下,8个数位最多是8个1,而8是1000,所以只需要4位就能表示出来,也就说明这里的每8个数位一组的前4个数位都是0。

剩下的两行也是同样的道理进行合并,至于为什么没有&,因为这时高位上均是0,不会产生影响。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值