对于以下程序:
public class ZeroFillRightShift
{
public static void main(String args[])
{
int x = -1;
int y = x>>>1;
System.out.println("x = " + x);
System.out.println("y = " + y);
}
Run Code Online (Sandbox Code Playgroud)
我得到如下输出:
x = -1
y = 2147483647
Run Code Online (Sandbox Code Playgroud)
我得到的结果-1>>>1是2147483647.如果它是必须移位的符号位,正如我所知,结果应该是1073741824.为什么它是2147483647呢?
下图更清楚地说明了我的问题:
无符号右移运算符">>>"将零移动到最左侧位置,而">>"之后的最左侧位置取决于符号扩展.
因此,-1向右移位一位,具有零扩展,这意味着它将向最左侧位置插入0.请记住,我们在这里处理两个补码:
-1是:11111111111111111111111111111111或0xFFFFFFFF十六进制
-1 >>> 1是01111111111111111111111111111111或0x7FFFFFFF以十六进制表示,
即2 31 - 1 == 2147483647
这是移位运算符的JLS参考.
你似乎对两个人的补充感到困惑.31位用于值,最左边的位用于符号.由于您只移位1位,因此有符号位变为0,这意味着为正,结果是最大正数而不是int可以表示的.
也许另一个例子会有帮助.我们考虑以下几点:
System.out.println(-2 >> 1); //prints -1
Run Code Online (Sandbox Code Playgroud)
-2 = 11111111111111111111111111111110
如果我们使用带符号的右移,我们得到:11111111111111111111111111111111,即-1.但是,如果我们这样做:
System.out.println(-2 >>> 1); //prints 2147483647
Run Code Online (Sandbox Code Playgroud)
因为-2 = 11111111111111111111111111111110并且做了一个无符号右移,这意味着我们用零扩展移位1位,给出:01111111111111111111111111111111