Sep 25, 2021 at 1:57am UTC
10 years ago I worked as a developer in c++, my fundamentals are great. Anyway, here is the code I have been playing with to come up to speed.
#include <concepts>
#include <limits>
#include <iostream>
// bit_width including the sign-bit
template < std::integral N > consteval std::size_t bit_width(N = {}) noexcept
{
return std::numeric_limits< std::make_unsigned_t<N> >::digits;
}
// set the most significan bit (including the sign-bit)
template < std::integral N > constexpr N set_msb(N n = 0 ) noexcept
{
return n | (N(1) << (bit_width<N>() - 1));
}
template < std::integral TypeOfInt >
TypeOfInt reverse(TypeOfInt toReverse) noexcept
{
constexpr TypeOfInt HIGH_BIT = set_msb< TypeOfInt >();
TypeOfInt reversed(0);
TypeOfInt countBit(1);
while (toReverse)
{
if (toReverse & HIGH_BIT)
{
reversed |= countBit;
}
toReverse <<= 1;
countBit <<= 1;
}
return reversed;
}
template<>
unsigned int reverse(unsigned int toReverse) noexcept
{
// swap odd and even bits
toReverse = ((toReverse >> 1) & 0x55555555) | ((toReverse & 0x55555555) << 1);
// swap consecutive pairs
toReverse = ((toReverse >> 2) & 0x33333333) | ((toReverse & 0x33333333) << 2);
// swap nibbles ...
toReverse = ((toReverse >> 4) & 0x0F0F0F0F) | ((toReverse & 0x0F0F0F0F) << 4);
// swap bytes
toReverse = ((toReverse >> 8) & 0x00FF00FF) | ((toReverse & 0x00FF00FF) << 8);
// swap 2-byte long pairs
toReverse = (toReverse >> 16) | (toReverse << 16);
return toReverse;
}
template<>
int reverse(int toReverse)
{
return reverse<unsigned int>(toReverse);
}
template<>
unsigned long long reverse(unsigned long long toReverse) noexcept
{
// swap odd and even bits
toReverse = ((toReverse >> 1) & 0x5555555555555555) | ((toReverse & 0x5555555555555555) << 1);
// swap consecutive pairs
toReverse = ((toReverse >> 2) & 0x3333333333333333) | ((toReverse & 0x3333333333333333) << 2);
// swap nibbles ...
toReverse = ((toReverse >> 4) & 0x0F0F0F0F0F0F0F0F) | ((toReverse & 0x0F0F0F0F0F0F0F0F) << 4);
// swap bytes
toReverse = ((toReverse >> 8) & 0x00FF00FF00FF00FF) | ((toReverse & 0x00FF00FF00FF00FF) << 8);
// swap 2-byte long pairs
toReverse = ((toReverse >> 16) & 0x0000FFFF0000FFFF) | ((toReverse & 0x0000FFFF0000FFFF) << 16);
toReverse = (toReverse >> 32) | (toReverse << 32);
return toReverse;
}
template<>
long long reverse(long long toReverse) noexcept
{
return reverse<unsigned long long>(toReverse);
}
int
main(int, char **)
{
std::cout << std::hex << reverse<unsigned char>(0x39) << std::endl;
std::cout << std::hex << reverse<char>(0x39) << std::endl;
std::cout << std::hex << reverse<unsigned short>(0x39) << std::endl;
std::cout << std::hex << reverse<short>(0x39) << std::endl;
std::cout << std::hex << reverse<unsigned int>(0x39) << std::endl;
std::cout << std::hex << reverse<int>(0x39) << std::endl;
std::cout << std::hex << reverse<unsigned long long>(0x39) << std::endl;
std::cout << std::hex << reverse<long long>(0x39) << std::endl;
return 0;
}
Emily@DESKTOP-K2S7IMO ~/programming/Reverse
$ ./Reverse.exe
▒
▒
9c00
9c00
9c000000
9c000000
9c00000000000000
9c00000000000000
Feel free to let me know what you think.
Sep 25, 2021 at 7:11am UTC
Implementing a Fourier transform?