我需要计算floor(log2(n))
,其中n
是最多64位的正整数。
值floor(log2(n))
等于n
的位长减1,因此标题。
我已实现以下功能:
uint8_t floorLog2(uint64_t n)
{
uint8_t res = 0;
uint64_t ONE = 1;
for (uint8_t k = 32; k > 0; k >>= 1)
{
if (n >= (ONE << k))
{
n >>= k;
res |= k;
}
}
return res;
}
效果很好,但是......
我已经意识到,对于6位数字,它的效率低于直接的方法:
uint8_t floorLog2(uint64_t n)
{
uint8_t res = 0;
while (n > 1)
{
n >>= 1;
res += 1;
}
return res;
}
所以我创建了一个组合版本:
uint8_t floorLog2(uint64_t n)
{
uint8_t res = 0;
if (n < 64)
{
while (n > 1)
{
n >>= 1;
res += 1;
}
}
else
{
uint64_t ONE = 1;
for (uint8_t k = 32; k > 0; k >>= 1)
{
if (n >= (ONE << k))
{
n >>= k;
res |= k;
}
}
}
return res;
}
但我不喜欢这里的分支(if
/ else
)。
由于我多次调用此函数,因此会影响程序的整体性能。
我在这里缺少更好的方法吗?
任何想到你的想法都会受到赞赏。
谢谢。
答案 0 :(得分:0)
uint8_t floorLog2(uint64_t n)
{
uint8_t res = 0;
static const uint64_t ONE = 1;
for (uint8_t k = 128; n >= 64; k >>= 1)
{
if (n >= (ONE << k))
{
n >>= k;
res |= k;
}
}
while (n > 1)
{
n >>= 1;
res += 1;
}
return res;
}