计数位
一个无符号的 32 位整数 u 可以这样写:
u = a<sub>31</sub> * 2<sup>31</sup> + a<sub>30</sub> * 2<sup>30</sup> + ... + a<sub>0</sub> * 2<sup>0</sup>
我们想要a<sub>31</sub> + a<sub>30</sub> + ... + a<sub>0</sub> 的值。
我们比较一下u >> k的值:
u >> 0 = a
31 * 2
31 + a
30 * 2
30 + ... + a
1 * 2
1 + a
0 * 2
0
u >> 1 = a
31 * 2
30 + a
30 * 2
29 + ... + a
1 * 2
0
u >> 2 = a
31 * 2
29 + a
30 * 2
28 + ...
...
u >> 29 = a
31 * 2
2 + a
29 * 2
1 + ...
u >> 30 = a
31 * 2
1 + a
30 * 2
0
u >> 31 = a
31 * 2
0 我们将通过这个公式计算比特人口:
u >> 0 - u >> 1 - u >> 2 - ... - u >> 31 = p
让我们看看为什么会这样:
u >> 0 - u >> 1 - u >> 2 - ... - u >> 31
= u >> 0 - (u >> 1 + u >> 2 + ... + u >> 31)
= u - q
q 的值是多少?让我们一点一点地计算它,看看上面u >> k 的值。对于a<sub>31</sub>,它是:
a
31 * 2
30 + a
31 * 2
29 + ...
= a
31 * (2
30 + 2
29 + ...)
= a
31 * (2
31 - 1)
或者a<sub>30</sub>:
a
30 * 2
29 + a
30 * 2
28 + ...
= a
30 * (2
29 + 2
28 + ...)
= a
30 * (2
30 - 1)
我们发现:q = a<sub>31</sub> * (2<sup>31</sup> - 1) + a<sub>30</sub> * (2<sup>30</sup> - 1) + ...
因此
u - q = a
31 * 2
31 - a
31 * (2
31 - 1) + .. .
= a
31 + a
30 + ... + a
0计算 3 位块中的位数
这个算法开始做同样的事情,但在 3 位块中:
u >> 0 = AaBbbCccDddEeeFffGggHhhIiiJjjKkk (each letter is a bit)
u >> 1 & 033333333333 = A Bb Cc Dd Ee Ff Gg Hh Ii Jj Kk (blank = zero)
u >> 2 & 011111111111 = B C D E F G H I J K
通过上述算法,uCount中的每个八位字节包含u中相应八位字节中设置的位数。
uCount = αβγδεζηθικλ (each greek letter is an octet)
uCount >> 3 = αβγδεζηθικ
所以uCount + (uCount >> 3) 是(λ+κ) * 2<sup>0</sup> + (κ+ι) * 2<sup>3</sup> + (ι+θ) * 2<sup>6</sup> + ...
通过与0o30707070707 进行与运算,我们屏蔽了所有其他八位字节,因此我们只对每一对计数一次:
r = (λ+κ) * 20 + (ι+θ) * 26 + (η+ζ) * 212支持> + ...
= (λ+κ) * 640 + (ι+θ) * 641 + (η+ζ) * 642 + 。 ..
这是一个 base-64 数字,我们想将 base-64 数字相加得到 α+β+γ+δ+ε+ζ+η+θ+ι+κ+λ,我们的最终结果。为此,我们计算它的 base-64 digital root:知道结果永远不会大于 32,我们只需将数字取模 63。