我遇到了这一堆,似乎应该有更好的方法来做到这一点。我想用bit twiddling来完成与以下内容相同的事情:
uint8_t nextlog(uint32_t n) {
return (uint8_t) ceil(log2(n)) + 1;
}
使用示例:
nextlog(0) -> undefined
nextlog(1) == 1
nextlog(3) == 3 // 0b11 -{next power 2}-> 0b100 -{log2+1}-> 3
nextlog(32) == 6 // 0b00100000 -{log2+1}-> 6
nextlog(71) == 8 // 0b01000111 --> 0b10000000 -> 8
我提出的最好的方法是将众所周知的bit twiddling hacks引用中的“舍入到下一个最高2的幂”和“查找整数的整数对数2”组合起来。我认为值得注意的是__builtin_clz
可以帮助完成问题的后半部分。
答案 0 :(得分:2)
你想要32 - clz(x)
,尽管你声称相反。
你声称log 2 0b100是3,这是数学中的错误。正确的答案是2。
它不在" bit twddling hacks"页面,但我发现了这个:
int clz(uint32_t x) {
x |= x >> 1;
x |= x >> 2;
x |= x >> 4;
x |= x >> 8;
x |= x >> 16;
return 32 - popcount(x);
}
int popcount(uint32_t x) {
x = x - ((x >> 1) & 0x55555555);
x = (x & 0x33333333) + ((x >> 2) & 0x33333333);
return (((x + (x >> 4)) & 0x0f0f0f0f) * 0x01010101) >> 24;
}
请注意,与x86上的ffs
相比,我确信性能有点糟糕。
答案 1 :(得分:0)
根据@Mark Dickinson的评论,单个分支的明显解决方案如下:
uint8_t nextlog(uint32_t n) {
if (n == 1) return 1;
return 33 - __builtin_clz(n - 1);
}