c++11 - 在编译时计算以 2 为底的整数对数的正确方法是什么?

标签 c++11 constants constexpr logarithm idioms

我有一些来自与我不同的库的正常数值,称之为 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 函数,但我敢打赌,我可以在编译时使用其他更简单、更便携的函数。 ......问题是,那会是什么?

最佳答案

最直接的解决方案是使用 std::log2来自 <cmath> ,但没有指定为 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; }

关于c++11 - 在编译时计算以 2 为底的整数对数的正确方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35311711/

相关文章:

c++ - 默认初始化与从默认构造值复制初始化

c++ - Cereal 序列化和多态性

javascript - 为什么函数声明中的常量声明不会抛出错误?

constants - "const"和 "val"有什么区别?

c++ - GCC 4.9 constexpr 错误的解决方法

c++ - C++ 编译器可以缓存 constexpr 函数的结果吗?

c++ - 重载运算符 << Boost Log

c++ - 循环范围拆分中的变量预评估

constants - 将 ⊤ ("down tack") 字符定义为我可以在我的程序中使用的常量

c++ - 为什么完全 `constexpr`启用数据结构会导致编译后的代码更大?