popcount函数返回输入中1的数目0010 1101popcount值为4。
目前,我正在使用此算法获取popcount

private int PopCount(int x)
{
    x = x - ((x >> 1) & 0x55555555);
    x = (x & 0x33333333) + ((x >> 2) & 0x33333333);
    return (((x + (x >> 4)) & 0x0F0F0F0F) * 0x01010101) >> 24;
}

这工作得很好,我要求更多的唯一原因是,这个操作运行得非常频繁,我正在寻找额外的性能提高。
我正在寻找一种简化算法的方法,因为我的1总是右对齐的。也就是说,输入将类似于00000 11111(返回5)或00000 11111 11111(返回10)。
有没有一种方法可以基于这个约束来提高popCount的效率?如果输入是01011 11101 10011,它只返回2,因为它只关心最合适的。似乎任何类型的循环都比现有解决方案慢。

最佳答案

这是一个执行“查找最高集”(二进制对数)的C#实现它可能比您当前的popcount快,也可能不快,它肯定比使用真正的clz和/或popcntcpu指令慢:

static int FindMSB( uint input )
{
    if (input == 0) return 0;
    return (int)(BitConverter.DoubleToInt64Bits(input) >> 52) - 1022;
}

测试:http://rextester.com/AOXD85351
以及没有条件分支的轻微变化:
/* precondition: ones are right-justified, e.g. 00000111 or 00111111 */
static int FindMSB( uint input )
{
    return (int)(input & (int)(BitConverter.DoubleToInt64Bits(input) >> 52) - 1022);
}

关于c# - 在有限制的情况下寻找更有效的弹出计数,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/29322554/

10-09 08:19