简体   繁体   English

按位-bitCount的公式含义是什么?

[英]Bitwise - bitCount's formula meaning?

here is the copy of the code from Integer.bitCount(int i) 这是Integer.bitCount(int i)中代码的副本

I understand all the operators but don't understand how those magic numbers can find out the count! 我了解所有运算符,但不了解这些魔术数字如何找出计数! can anyone explain that to me? 谁能向我解释? I can see the pattern (1,2,4,8,16 & 0x5,0x3,0x0f). 我可以看到模式(1,2,4,8,16&0x5,0x3,0x0f)。

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

OK, your code is for 32 bit integers, but let's figure out the first step for 16 bit since the alphabet doesn't have 32 letters. 好的,您的代码是32位整数,但由于字母表没有32个字母,因此让我们找出第一步是16位。 Assume the binary form of your input (with byte boundaries indicated by spaces) is 假设输入的二进制形式(字节边界由空格表示)为

i                  = ABCDEFGH IJKLMNOP
i >>> 1            = 0ABCDEFG HIJKLMNO
(i >>> 1) & 0x5555 = 0A0C0E0G 0I0K0M0O

So the first two bits of the right hand side in the first assignment are (AB - 0A) . 因此,第一个分配中右侧的前两位是(AB - 0A) Try the combinations: 尝试组合:

A  B  AB-0A
0  0  00-00 = 00
1  0  10-01 = 01
0  1  01-00 = 01
1  1  11-01 = 10

So the first two bits of that result give you the count of bits in the first two bits of the input. 这样结果的前两位给你位的计数输入的前两位。 The same holds for all the other groups of two bits. 所有其他两个两位的组也一样。

Now you do the same thing again. 现在,您再次执行相同的操作。 This time we'll consider input in base 4, so two bits form a digit of the notation below, and we can use full 32 bits. 这次我们将考虑以4为底的输入,因此两位由下面的符号组成,我们可以使用完整的32位。

i                      = ABCD EFGH IJKL MNOP
i & 0x33333333         = 0B0D 0F0H 0J0L 0N0P
i >>> 2                = 0ABC DEFG HIJK LMNO
(i >>> 2) & 0x33333333 = 0A0C 0E0G 0I0K 0M0O

So the first four bits of the result are (0A + 0B) = A + B , and the same holds for any other group of four bits. 因此,结果的前四位是(0A + 0B) = A + B ,其他四位组也是如此。 So at that point, every group of four bits contains the bit count of these four bits in the original input. 因此,在这一点上,每组四位包含原始输入中这四位的位数。

Using base 16, the next step is 使用基数16,下一步是

i                            = AB CD EF GH
i >>> 4                      = 0A BC DE FG
i + (i >>> 4)                = A(A+B) (B+C)(C+D) (D+E)(E+F) (F+G)(G+H)
(i + (i >>> 4)) & 0x0f0f0f0f = 0(A+B) 0(C+D) 0(E+F) 0(G+H)

This works because the bit count in each four-bit-group will always be less than four, so adding two such counts can be represented in four bits without overflow. 之所以可行,是因为每个四位组中的位计数始终小于4,因此可以将两个这样的计数相加,就可以用四位表示,而不会发生溢出。 Therefore the addition will not have any overflow from one four-bit base-16 digit to another. 因此,加法运算不会从一个四位的基数16位到另一位溢出。 At this point, you have each byte containing the bit count for that byte of the input. 此时,每个字节都包含输入字节的位数。 Other algorithms may contine from there using clever multiplication, but the code you quoted sticks to addition for the next steps as well. 其他算法也可以使用聪明的乘法从那里进行转换,但是您引用的代码对于后续步骤也同样适用。

i                           = A B C D
i >>> 8                     = 0 A B C
i2 = i + (i >>> 8)          = A (A+B) (B+C) (C+D)
i2 >>> 16                   = 0 0 A (A+B)
i3 = i2 + (i2 >>> 1         = A (A+B) (A+B+C) (A+B+C+D)
i3 & 0x3f                   = 0 0 0 (A+B+C+D)

Again this makes use of the fact that there is no overflow between digits. 同样,这利用了数字之间没有溢出的事实。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM