How does one get the width of an general int

Pages: 12
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.
PLEASE learn to use code tags, they make reading and commenting on source code MUCH easier.

http://www.cplusplus.com/articles/jEywvCM9/
http://www.cplusplus.com/articles/z13hAqkS/

HINT: you can edit your post and add code tags.

Some formatting & indentation would not hurt either
Reverse bits in constant values at compile-time:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
#include <concepts>
#include <limits>

// 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 ;
}

// swap the bits at the two positions
template < std::unsigned_integral N >
constexpr N swap_bits( N number, std::size_t pos_high, std::size_t pos_low ) noexcept
{
    const N bit_one = ( number >> pos_high ) & 1U ;
    const N bit_two = ( number >> pos_low ) & 1U ;
    const N x = bit_one ^ bit_two ;
    const N y = ( x << pos_high ) | ( x << pos_low ) ;
    return number ^ y ;
}

namespace compile_time
{
    // reverse all bits (by recursively swapping bits)
    template < std::unsigned_integral N >
    constexpr N reverse_bits( N number, std::size_t pos_high, std::size_t pos_low ) noexcept
    {
        if( pos_high <= pos_low ) return number ;
        else return reverse_bits( swap_bits(number,pos_high,pos_low), pos_high-1, pos_low+1 ) ;
    }
}

namespace run_time
{
    // reverse all bits efficiently at run-time
    template < std::integral N >
    N reverse_bits( N number ) noexcept ; // *** not implemented
}

template < std::integral N >
constexpr N reverse_bits( N number ) noexcept
{
    if( std::is_constant_evaluated() )
       return compile_time::reverse_bits( std::make_unsigned_t<N>(number), bit_width<N>()-1, 0 ) ;
    else
       return run_time::reverse_bits(number) ;
}

https://gcc.godbolt.org/z/hcnToav15

With a trivial test frame: http://coliru.stacked-crooked.com/a/4e2b015ee4c7ae75
Implementing a Fourier transform?
Topic archived. No new replies allowed.
Pages: 12