jdk提供的bitCount函数理解

问题

  bitCount源码解析:基于jdk1.8

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

算法作用:统计整数的二进制表达中1的个数。

算法核心思想

  1、依次将整数的二进制序列分为单位大小为2,4,6,8,16,32的子序列;在每个划分阶段,子序列内部对等分后相加

  2、数据的批量处理。

 

步骤

  1、以2为单位进行划分:i = i - ((i >>> 1) & 0x55555555);

00 0
01 1
10 1
11 2

规律总结:如果高位是0,则结果和数值本身相同(参数-0);如果是高位是1,则数值本身-1得到结果(参数-1)。

公式提炼:结果 = 参数 - (参数 >>>1 & 01)

分析:0x55555555 = 01010101010101010101010101010101,(参数 >>>1 &0x55555555)表示计算每个子序列中的高位, (参数 - (参数 >>>1 & 0x55555555))则是计算出每个单位内1的个数(以2位单位进行划分)。

 

  1.1、另一种表达形式:i= (i &0x55555555) + ((i >>1) &0x55555555) ;

分析:结果相同。批量计算以2为单位的每个子序列内1的个数,(i &0x55555555)获得低1位值,((i >>1) &0x55555555)获得高1位值。

原理示例:

7                01110x5              0101
=============================
i1 = (3 & 0x5) 0101 i2 = (3>>>1 & 0x5) 0001
=============================
i = i1+i2 0110 01 -> 01 1个1 11 -> 10 2个1

 

  比较:方式1做的运算更少,效率更高。

  

  2、以4为单位进行划分:i = (i & 0x33333333) + ((i >>> 2) & 0x33333333);

分析:运算原理同1.1方式。(i & 0x33333333)获得低2位,((i >>> 2) & 0x33333333)获得高2位,另一个目的是为了防止高位污染,因为计算步骤1后,最大值为 0010(2),所以在此单位内计算得到的最大值为0100(4),需要占用到高位的位置,所以通过掩码(0x33333333)对高两位清零。

 

  3、以8位单位进行划分:i = (i + (i >>> 4)) & 0x0f0f0f0f;

分析:对步骤2计算过程的优化,因为此单位内的最大值为0000 1000(8),不需要使用到高位,所以直接进行i + (i >>> 4)),但是此时高位仍存在无效值,所以使用掩码0x0f0f0f0f清零高4位,确保值得正确性。

 

  4、以16位单位进行划分:i = i + (i >>> 8);

分析:对步骤3计算过程的优化。此单位内的最大值为0000 0000 0001 0000(16),不需要使用到高8位,并且int型最多32个1(32位),使用6位就可以表达。而8位可以表达128个1,所以高8位根本不会再参与后续的计算,再后续的计算中默认值只取后6位。补充:long型取后7位。

  5:以32位单位进行划分:i = i + (i >>> 16)

分析:对步骤4计算过程相同,只是把计算单位扩大到32.

 

  6:i & 0x3f

分析:截取结果的后6位:0011 1111(32)。补充:long型使用i&0x7f,0111 1111(64)。

 

总结:

(1)感觉有点类似于归并思想,先计算子序列,然后合并,最终获得结果。

 

(2)掩码的使用:

  》计算结果需要使用到高位:移位->掩码清零->相加

  》计算结果不需要到高位:

          》高位依然要参与到后续的计算:移位->相加->掩码清零

           》高位依然不需要参与到后续的计算:移位->相j加

 

参考博客:

  (1)https://blog.csdn.net/u013706904/article/details/89285482(函数解析)

  (2)https://www.it610.com/article/5225312.htm(EnumSet解析)

 

posted @ 2020-05-19 11:27  Yrc的楚门的世界  阅读(363)  评论(0)    收藏  举报