The bit twiddling hacks website propose the following very efficient function to reverse bits:
// Bitswap: reverse the bits of the value of unsigned integral type T
template <class T>
constexpr T bitswap(T src)
{
constexpr std::size_t char_bit = std::numeric_limits<unsigned char>::digits;
constexpr std::size_t digits = sizeof(T) * char_bit;
std::size_t size = digits;
T mask = ~T();
while ((size >>= 1) > 0) {
mask ^= (mask << size);
src = ((src >> size) & mask) | ((src << size) & ~mask);
}
return src;
}
__uint128_t
? (the original version works with __uint128_t
)digits
is correctly initialized to the correct number of bits? (for example a hypotherical uint41_t
).You can't enforce rolling out templated calls, but chances are, this will end up in one single inlined function in an optimized build:
#include <iostream>
#include <limits>
#include <iomanip>
template <class T, int size = ((std::numeric_limits<unsigned char>::digits
* sizeof(T)) >> 1)>
struct Swap
{
static constexpr T bitswap(T src, T mask = ~T())
{
mask ^= (mask << size);
src = ((src >> size) & mask) | ((src << size) & ~mask);
return Swap<T, (size >> 1)>::bitswap(src, mask);
}
};
template <class T>
struct Swap<T, 0>
{
static constexpr T bitswap(T src, T mask)
{
return src;
}
};
template <class T>
constexpr T bitswap(T src)
{
return Swap<T>::bitswap(src);
}
int main() {
std::cout << std::hex << bitswap(0x12345678l);
}
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