什么是在编译时计算积分基2对数的正确方法?

时间:2016-02-10 09:49:14

标签: c++11 constants constexpr logarithm idiomatic

我有一些来自与我不同的库的正常数值,称之为the_val。现在,我希望log_of_the_val成为底层(log_2(the_val)) - 不是用C ++代码说话 - 我当然希望在编译时发生这种情况。

现在,使用gcc,我可以做类似

的事情
decltype(the_val) log_of_the_val = sizeof(the_val) * CHAR_BIT - __builtin_clz(the_val) - 1;

这应该有效,我认为(长度 - 标题零的数量)。否则,我可以自己实现一个constexpr函数,但是我打赌我可以在编译时使用其他更简单,更便携的东西。 ......问题是,那会是什么?

1 个答案:

答案 0 :(得分:5)

最直接的解决方案是使用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; }