为什么 -1 << 23 和 -1 << 55 return 在 Java 中的值相同?

Why does -1 << 23 and -1 << 55 return the same value in Java?

为什么 -1 << 23 和 -1 << 55 return 在 Java 中的值相同?看起来它们应该有很大的不同,因为我正在移动更多的地方!但是,它们产生相同的值。为什么会这样?

public class BitShifting {
  public static void main(String... args) {
    long foo = -1 << 23;
    long bar = -1 << 55;

    System.out.println(foo);
    System.out.println(bar);
  }
}

输出:

-8388608
-8388608

因为 1 是一个 int,而不是 long,并且到 long 的转换直到赋值语句之后才会发生。 Java 会注意到左边的参数是 int 而不是 long,并将相应地舍入右边的值。

From the JLS:

If the promoted type of the left-hand operand is int, only the five lowest-order bits of the right-hand operand are used as the shift distance. It is as if the right-hand operand were subjected to a bitwise logical AND operator & (§15.22.1) with the mask value 0x1f (0b11111). The shift distance actually used is therefore always in the range 0 to 31, inclusive.

如果用 1L 声明左侧参数,则行为将符合预期,如下所示:

public class BitShifting {
  public static void main(String... args) {
    long foo = -1L << 23;
    long bar = -1L << 55;

    System.out.println(foo);
    System.out.println(bar);
  }
}

输出:

-8388608
-36028797018963968