还要注意 bitcount(2n) = bitcount(n)
推导如下:
让 n = sum(b[j] 2^j) for j=0...N
假设 b[N] = 1. 定义
(a) F(n) = n + F(n/2) = n+n/2+n/4+... = 2 * n - (1/2 + 1/4 + ... 1/2^N) 几何级数
这个函数 F 是一个实值函数。现在对于设置的每个位 b[j],floor 函数减去 b[j](sum(1/2^k, k=1...j+1))。这是因为它实际上取出了 1/2,但是随着它的传播,后续的项被添加了。
所以
(b) f(n) = floor(F(n)-sum(b[j] sum(1/2^k, k=1...j+1), 对于 j=0... N-1)
将 (a) 代入 (b) 得到
(c) f(n) = floor(2n - (1/2 + 1/4 + ... 1/2^(N+1)) - sum(b[j] (sum(1/2^(k), for k=1..j+1), for j=0...N-1))
好的,这部分很酷!观察当b[j]为1时,如果把粗体表达式中的1/2^(j+1)偷偷到斜体的sum里面,sum里面的sum变成1,也就是说
b[j] (sum(1/2^(k), for k=1..j+1), for j=0...N-1) = sum(b[j], for j =0...N-1)
所以方程(c)简化为
f(n) = floor(2*n - sum(b[j], for j=0...N-1) - remainder)
f(n) = 2*n - bitcount(n-2^N) - 1 ; because remainder >0 and <1
f(n) = 2*n - bitcount(n) ; b[N]=1, so bitcount(n)=bitcount(n-2^N)+1
其中余数是 sum(1/2^j, j=1,..N+1 and b[j-1]==0),但这个总和总是 >0 且
还要注意,bitcount 运行时间可以等于设置的位数 (http://gurmeet.net/puzzles/fast-bit-counting-routines/)。一些处理器将其作为单独的指令。
不确定乳胶是否在这里有效,但没有数学符号会很痛苦。我一直不得不编辑它,因为看起来总是有问题。