在 compile-time 处计算以 2 为底的整数对数的正确方法是什么?
What's the right way to compute integral base-2 logarithms at compile-time?
我有一些来自与我不同的库的正常数值,称之为 the_val
。现在,我希望 log_of_the_val
成为 floor(log_2(the_val)) - 不是用 C++ 代码说话 - 当然,我希望它发生在编译时。
现在,有了 gcc,我可以做类似的事情
decltype(the_val) log_of_the_val = sizeof(the_val) * CHAR_BIT - __builtin_clz(the_val) - 1;
我认为这应该可行(长度 - 标题零的数量)。否则,我可以自己为它实现一个 constexpr 函数,但我打赌还有其他更简单、更便携的东西,我可以在 compile-time 上使用。 ...问题是,那会是什么?
最直接的解决方案是使用 <cmath>
中的 std::log2
,但未指定为 constexpr - 它在 gcc 下,但不在 clang 下。 (其实libstdc++std::log2
调用__builtin_log2
,就是gcc下的constexpr。)
__builtin_clz
在 gcc 和 clang 下都是 constexpr,所以你可能想使用它。
完全可移植的解决方案是编写递归 constexpr 积分 log2:
constexpr unsigned cilog2(unsigned val) { return val ? 1 + cilog2(val >> 1) : -1; }
我有一些来自与我不同的库的正常数值,称之为 the_val
。现在,我希望 log_of_the_val
成为 floor(log_2(the_val)) - 不是用 C++ 代码说话 - 当然,我希望它发生在编译时。
现在,有了 gcc,我可以做类似的事情
decltype(the_val) log_of_the_val = sizeof(the_val) * CHAR_BIT - __builtin_clz(the_val) - 1;
我认为这应该可行(长度 - 标题零的数量)。否则,我可以自己为它实现一个 constexpr 函数,但我打赌还有其他更简单、更便携的东西,我可以在 compile-time 上使用。 ...问题是,那会是什么?
最直接的解决方案是使用 <cmath>
中的 std::log2
,但未指定为 constexpr - 它在 gcc 下,但不在 clang 下。 (其实libstdc++std::log2
调用__builtin_log2
,就是gcc下的constexpr。)
__builtin_clz
在 gcc 和 clang 下都是 constexpr,所以你可能想使用它。
完全可移植的解决方案是编写递归 constexpr 积分 log2:
constexpr unsigned cilog2(unsigned val) { return val ? 1 + cilog2(val >> 1) : -1; }