-1 左移 31

-1 left shift by 31

System.out.println((-1<<31));

为什么输出 -2147483648

我知道 -1<<31 会给出 10000000000000000000000000000000,所以它应该给出等于 2147483648

的答案 (int)Math.pow(2,31)

-1<<31 给出 10000000000000000000000000000000,即 -2147483648,而不是 2147483648。注意左边的位是符号位,所以如果是1,就是负数。

顺便说一句,1<<31 也会给你 -2147483648,因为 2147483648Integer.MAX_VALUE 高。另一方面,1L<<31 会给你 2147483648,因为结果将是 long.

I know -1<<31 will give 100000000000000000, so it should give ans (int)Math.pow(2,31) that is equals to 2147483648

如果 int 是二进制补码 unsigned 原语,情况就是如此;但 int 已签名。

事实上你是对的,在二进制中这确实给出了你所说的;然而,由于这是一个带符号的二进制补码原语,结果将是 x(0) * 2^0 + x(1) * 2^1 + ... + x(n-2) * 2^(n-2 ) - x(n-1) * 2^(n-1)(减,不是加),其中x(y)是第y位的值,计数从 0.

因此你的结果。

现在大多数体系结构中的数字都存储在 2 补码中,请参阅 Wikipedia

所以你的结果是正确的。符号位已设置,所有剩余零(因为 2 补码)使该数据类型的负数最大,请参阅 here

2 补码的思考

-1 is represented by 1111 1111 1111 1111 1111 1111 1111 1111

向左移动 31 次得到

1000 0000 0000 0000 0000 0000 0000 0000 which represents -2.147.483.648