据我所知,汉明加权算法和popcnt可以有效地计算值中设置的位数。但是有没有类似的操作来计算位设置的索引?例如:
0010110
将返回7(索引1,2和4设置)
要清楚,我正在寻找尽可能低级别的实现。 我的目标是为长度为1024位的值执行此操作。
答案 0 :(得分:2)
如果您正在快速实现,我建议使用256个条目的查找表,为所有可能的字节值提供所需的总和(因为最大总和为28,这将适合一个字节)。 / p>
然后以字节为单位拆分整数(我不知道有多少,你没有指定)并累积查找值。
对于正确的总数,您必须在每个字节上调整索引的原点。两个选项
为不同的字节实现单独的表,
还使用位计数表来计算校正(8 x字节索引x位计数)。
unsigned char Byte0Sum[256]= { 0, 0, 1, 1, 2, 2, 3, 3, ... };
unsigned char Byte1Sum[256]= { 0, 8, 9, 17, 10, 18, 19, 27, ... };
...
unsigned Total= ByteSum0[N & 255] + ByteSum1[(N >> 8) & 255] + ...;
或
unsigned char ByteCount[256]= { 0, 1, 1, 2, 1, 2, 2, 3, ... };
unsigned char ByteSum[256]= { 0, 0, 1, 1, 2, 2, 3, 3, ... };
...
unsigned Total= ByteSum[N & 255] + ByteSum[(N >> 8) & 255] + 8 * ByteCount[(N >> 8) & 255] + ...;
根据您的应用程序,可以使用其他表格大小。
答案 1 :(得分:1)
我不知道有任何built-in functions会这样做,所以也许一个简单的循环如下所示:
unsigned int bit_index_sum(unsigned int n) {
for (int i=1,s=0; i<sizeof(n)*8; i++) {
n >>= 1;
if (n & 1) s += i;
}
return s;
}
答案 2 :(得分:0)
int a = whatever;
int i = 0, sum = 0;
while(a){
if (a & 1){
sum += i;
}
a = a >> 1;
i++;
}
根据评论的建议,这对负数不起作用,除非你取绝对值并相应地在符号上添加符号。
答案 3 :(得分:0)
由于问题中未明确给出'value'的类型,我将假设七位,如给出的示例所示。
使用128字节的查找表并直接对其进行寻址。 XLAT或类似的。