如何有效地计算C中长字节序列中的一位总数?

时间:2016-04-10 23:19:13

标签: c bits

我正在阅读这本书programming pearls by Jon Bentley,我遇到了这个问题。

  

给定一个非常长的序列(比如数十亿或数万亿)字节,你如何有效地计算一位的总数? (即序列中打开了多少位)

我见过的大多数解决方案都不会被认为是有效的。您认为如何有效解决这个问题?

2 个答案:

答案 0 :(得分:4)

获取一个具有popc16指令的CPU(计算16字节大存储区中的一位; popc表示填充计数)并在展开的循环中调用该指令。

如果仍然太慢,请将数据拆分为多个块并在独立的计算机上处​​理它们。在拆分或合并数据时,请注意不要产生瓶颈。

如果您绑定到C,请检查您的编译器是否提供__builtin_popc函数。

如果不允许,请阅读“Hacker's Delight”一书。

答案 1 :(得分:1)

继Roland的回答之后,一个有效的方法来获得无符号(或一次4个字节)的1的数量是下面的逐位黑客攻击(我认为这是来自黑客的喜悦或者有点笨拙的黑客攻击)< / p>

int getn1s (unsigned x)
{
    x = x - ((x >> 1) & 0x55555555);
    x = (x & 0x33333333) + ((x >> 2) & 0x33333333);
    x = (x + (x >> 4)) & 0x0F0F0F0F;
    x = x + (x << 8);
    x = x + (x << 16);
    return x >> 24;
}

如果内联并在展开的循环中调用,那么结果应该提供一种相当有效的方法来计算1的字节数,就像你拥有的那样多。