public static int bitCount(int i) {
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;
}
自己在编写类似的方法时,有一个思路,供大家参考。
int类型是有符号类型的特点,当最高位为1时,表示一个负值。利用这一特点,通过左移位操作<<,
然后判断正负值,为负标明该位为1,正值标明该位为0。代码如下。
public static int bitCount(int i)
{
int count=0;//对二进制数中为1的位进行计数
for(int j=0;j<32;j++)
{
if(i<0)
count=++count;
i=i<<1;
}
return count;
}
Integer.bitCount中,
第一行是计算每两位中的 1 的个数,并且用该对应的两位来存储这个个数,
如: 01101100 -> 01011000 ,即先把前者每两位分段 01 10 11 00 ,分别有 1 1 2 0 个1,用两位二进制数表示为 01 01 10 00, 合起来为 01011000.
第二行是计算每四位中的 1 的个数,并且用该对应的四位来存储这个个数.
如: 01101100 经过第一行计算后得 01011000 ,然后把 01011000 每四位分段成 0101 1000 ,段内移位相加: 前段 01+01 =10 , 后段 10+00=10, 分别用四位二进制数表示为 0010 0010, 合起来为 00100010 .
下面的各行以此类推,分别计算每8位,16位,32位中的 1 的个数.
将 0x55555555, 0x33333333, 0x0f0f0f0f 写成二进制数的形式就容易明白了.
Integer.bitCount 的算法要比你的算法效率高的多了.因为它没有循环,而你的算法中有循环.