given
int a = 1;
(00000000000000000000000000000001
),
what I did is just
a=(a<<31)>>31;
Look at it in steps:
#include <cstdio>
using namespace std;
int main()
{
int a = 1;
printf("%d = %x\n", a, a);
a <<= 31;
printf("%d = %x\n", a, a);
a >>= 31;
printf("%d = %x\n", a, a);
return 0;
}
Output:
1 = 1
-2147483648 = 80000000
-1 = ffffffff
1 got shifted all the way up to the high bit which makes it a negative number. Shifting back down triggers sign extension to maintain the negative.
Change the declaration of a to unsigned int a
and you will get the behaviour you expect.
" however it turns out to be
-1
"
You use an unsigned int
to do so for seeing only 32 bit values that are greater than 0
:
unsigned int a = 1;
a=(a<<31)>>31;
What you are missing is that in C++ right shift >>
is implementation defined. It could either be logical or arithmetic shift for a signed value. In this case it's shifting in 1
s from the left to retain the sign of the shifted value. Typically you want to avoid doing shifts on signed values unless you know precisely that they will be positive or that the shift implementation doesn't matter.
It is a signed shift so the left most bit will be extended. That way the overall number is on the same side of 0.
By left shifting that much you put the lowest bit into the sign bit and end up with a negative number.
When you then do a right shift it sign extends, copying the sign bit down to the lower 31 bits.
If you want to know the lowest bit just do & 1
.