why shift int a=1 to left 31 bits then to right 31 bits, it becomes -1

假装没事ソ 提交于 2019-12-02 13:59:28

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 1s 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.

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;  

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.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!