template<class T, std::size_t...Is>
std::array<uint8_t, bytes> decomponse( std::index_sequence<Is...>, T in ) {
return {{ (uint8_t)( in >> (8*( (sizeof...(Is)) - Is ) )) }};
}
template<std::size_t bytes, class T>
std::array<int8_t, bytes> decomponse( T in ) {
return decompose( in, std::make_index_sequence<bytes>{} );
}
template<std::size_t bytes, class T>
double big_log2( T in ) {
auto bytes_array = decompose<bytes>(in);
std::size_t zeros = 0;
for (auto byte:bytes_array) {
if (byte) break;
++zeros;
}
int32_t tmp = 0;
for (auto i = zeros; (i < bytes) && i < (zeros+4); ++i) {
tmp |= bytes_array[i] << (8*(3 - (i-zeros)));
}
return log2(tmp) + (bytes-zeros-4)*8;
}
where log2(int32_t)
generates a log2 of a 32 bit value and returns a double
.
Depending on endianness, reversing bytes_array
and modfying algorithm may make it faster (ideally it should compile down to a memcpy or just be optimized out entirely).
This attempts to shove the 4 highest significance bytes into a int32_t, take its logarithm, then add the right amount to shift it to the magnitude of the N-byte integer in question.