对于Java中的整数,为什么-1为零填充右移1 = 2147483647?

Pra*_*nny 12 java bit-shift

对于以下程序:

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呢?

下图更清楚地说明了我的问题:

样本图片

Ste*_* P. 8

无符号右移运算符">>>"将零移动到最左侧位置,而">>"之后的最左侧位置取决于符号扩展.

因此,-1向右移位一位,具有零扩展,这意味着它将向最左侧位置插入0.请记住,我们在这里处理两个补码:

-1是:111111111111111111111111111111110xFFFFFFFF十六进制

-1 >>> 1是011111111111111111111111111111110x7FFFFFFF以十六进制表示,
即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

  • 你的意思是2**31 - 1? (2认同)