setting all but MSB on signed long long

Hi, I tried to write a little bit of code to set all bits within a signed int with exception to the MSB, yielding the greatest max positive value. The odd part is that it works for shorts ints, and longs, which are 2, 4 and 4 bytes respectively, however long longs, with a size of 8 bytes, simply yields -1, which would indicate that it failed to clear the MSB. Heres the little segment in question:

1
2
3
4
5
6
7
template<typename T>
T getMax()
{
    return my::numerics<T>::is_signed ?
                ~0 ^ (1 << ((sizeof(T)*8)-1) ):
                ~0;
}


my::numerics is just an exercise- its thoroughly tested and I'm certain thats not the issue.

For shorts, ints, longs, this yields the maximum value. However, when I use it on long longs, the output is 0xFFFFFFFFFFFFFFFF, ie ~0. Obviously this means the maximum value for unsigned long longs, but -1 for signed long longs.

Is there something I'm missing here?
You know std::numeric_limits<T> already have this, right?

there is a signed overflow in your code for T=short and left shift past the size of the type for T=long long (and for T=long where longs are bigger than ints), which are both examples of undefined behavior

you can fix the left shift overflow by changing line 5 to
~0 ^ (T(1) << ((sizeof(T)*8)-1) ):
Last edited on
Ahh, I see, thank you.

Also, I know numeric limits has this- this is purely for my benefit.
Topic archived. No new replies allowed.