I have some positive constant value that comes from a different library than mine, call it the_val
. Now, I want log_of_the_val
to be floor(log_2(the_val)) - not speaking in C++ code - and I want that to happen at compile time, of course.
Now, with gcc, I could do something like
decltype(the_val) log_of_the_val = sizeof(the_val) * CHAR_BIT - __builtin_clz(the_val) - 1;
and that should work, I think (length - number of heading zeros). Otherwise, I could implement a constexpr function myself for it, but I'm betting that there's something else, and simpler, and portable, that I could use at compile-time. ... question is, what would that be?
The most straightforward solution is to use std::log2
from <cmath>
, but that isn't specified to be constexpr - it is under gcc, but not under clang. (Actually, libstdc++ std::log2
calls __builtin_log2
, which is constexpr under gcc.)
__builtin_clz
is constexpr under both gcc and clang, so you may want to use that.
The fully portable solution is to write a recursive constexpr integral log2:
constexpr unsigned cilog2(unsigned val) { return val ? 1 + cilog2(val >> 1) : -1; }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With