如何有效地计算bigint值中设置位的索引?

时间:2017-09-18 09:03:36

标签: c bit-manipulation

据我所知,汉明加权算法和popcnt可以有效地计算值中设置的位数。但是有没有类似的操作来计算位设置的索引?例如:

0010110

将返回7(索引1,2和4设置)

要清楚,我正在寻找尽可能低级别的实现。 我的目标是为长度为1024位的值执行此操作。

4 个答案:

答案 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或类似的。