Тоже решал такую задачку, но пошёл по другому пути.
Суть метода: преобразовать целое число в double и уже из двоичного представления double извлечь степень двойки.
#include <type_traits>
/// Integral part of log2(n), n - integral (interpreted as unsigned)
template <class _Int, class = std::enable_if_t<std::is_integral<_Int>::value>>
constexpr int ilog2(_Int n) noexcept
{
struct Bits {
constexpr auto bias() const noexcept { return 1023; }
uint64_t m: 52;
uint64_t e: 11;
uint64_t s: 1;
};
union FRep {
constexpr FRep(double f) noexcept : v(f) {}
constexpr int ilog2() const noexcept
{ return b.e >= b.bias() ? int(b.e) - b.bias() : -1; }
double v;
Bits b;
};
return FRep(double(uint64_t(n))).ilog2();
}
/// Most significant bit // Старший значащий бит
/// @return 2^i or 0, i = index of the MSB;
template <class _Int, class = std::enable_if_t<std::is_integral<_Int>::value>>
constexpr auto msb(_Int n) noexcept
{
using Unsigned = std::make_unsigned_t<_Int>;
return !n ? 0 : n == _Int(-1) ? Unsigned(-1) ^ (Unsigned(-1) >> 1)
: Unsigned(1) << ilog2(n);
}
Тоже решал такую задачку, но пошёл по другому пути.
Суть метода: преобразовать целое число в double и уже из двоичного представления double извлечь степень двойки.