当我对1 << 63进行位移时,为什么Java会返回-2147483648?
预期结果应该是9 223 372 036 854 775 808
,使用 Wolfram Alpha 和我的计算器进行测试。
我进行了如下测试:
System.out.print((long)(1 << (63)));
当我对1 << 63进行位移时,为什么Java会返回-2147483648?
预期结果应该是9 223 372 036 854 775 808
,使用 Wolfram Alpha 和我的计算器进行测试。
我进行了如下测试:
System.out.print((long)(1 << (63)));
这一行有一个重要的注意事项。
System.out.print((long)(1 << (63)));
你首先要取 (1 << 63)
,然后将其转化为 long 类型。因此,实际上你是在整数中进行左移操作,所以 long 转换没有任何效果。这就是为什么将 63 比特左移得到的是最小整数而不是最小 long 的原因。
但还有一个更重要的点,Java 的 long 类型始终是有符号的,所以即使是以下这行代码
System.out.print(1L << 63);
如果使用二进制补码,若最左边的位是1,则会得到一个负数。
实际上,你无法用Java原始类型表示数字263 = 9223372036854775808,因为这个数字比最大的long类型还要大,而long
是最大的原始类型。不过,你可以用BigInteger表示这个数字。你甚至可以通过将63左移来生成它的代码:
BigInteger.ONE.shiftLeft(63)
您正在遭遇 整数溢出 [两次]。
1 << 32 == 1
1 << 31 == -2147483648 [ becuase this is the binary representation in 2's complement for -2147483648]
1 << 63 == 1 << (32 + 31) == (1 << 32) << 31 == 1 << 31 == -2147483648
(long)(1 << (63))
时,你只是将1 << (63)
的结果[即-2147483648
]转换为long
类型 - 但它并不改变其值。