计算O(1)中的汉明重量

时间:2013-03-05 20:08:00

标签: algorithm bit-manipulation

在二进制表示中,汉明重量是1的数。我遇到网络并找到了O(1)的答案:

v = v - ((v>>1) & 0x55555555);
v = (v & 0x33333333) + ((v>>2) & 0x33333333);
int count = ((v + (v>>4) & 0xF0F0F0F) * 0x1010101) >> 24;

但是我不太了解算法,无法在任何地方找到它的描述。有人可以解释一下,特别是最后一行(哎呀* 0x1010101然后>> 24意味着什么)?

1 个答案:

答案 0 :(得分:22)

这是计算比特的分而治之策略的一部分,称为“人口”功能。这种策略的学术性处理可以在Reingold和Nievergelt,1977年找到。

这个想法是首先将这些位成对,然后是4位,然后是8位,依此类推。例如,如果您有位1011,则第一对10变为01,因为有一位而第二对变为10因为10 = 2 in二进制,11中有两位。这里的基本事实是:

population(x) = x - (x/2) - (x/4) - (x/8) - (x/16) - ... etc.

您拥有的确切算法是所谓的“HAKMEM”算法的变体(参见Beeler,Gosper和Schroppel,1972)。该算法并行计算4位字段中的1,然后将这些和转换为8位和。最后一步是通过乘以0x01010101来添加这4个字节的操作。 0x0F0F0F0F掩码通过屏蔽非和信息来获得4个字节的总和。例如,假设8-wise字段为10110110,则有5位等于0101,因此我们将10110101。只有最后四位是重要的,所以我们屏蔽了前四位,即:

10110101 & 0x0F = 00000101

你可以在亨利·沃伦的“黑客喜悦”一书中找到关于计算位数的细节的整章。