假设我们有 int n = 2 ^ 31
然后 n-1 = 0111111111111111111111111111111
,这是我在本地可以得到的。
我的猜测:首先将n
转换为long
-> 减法 -> 切片以适合int
。
System.out.println(n);
System.out.println(Integer.toBinaryString(n-1) + " : " + Integer.bitCount(n-1));
System.out.println(n-1);
// output
-2147483648
1111111111111111111111111111111 : 31
2147483647
但是我没有找到规范来验证我的猜测,有吗?
When an arithmetic operation produces a result larger than the maximum above for an N-bit integer, an overflow reduces the result to modulo N-th power of 2, retaining only the least significant bits of the result and effectively causing a wrap around.
如果我的猜测完全错误,那么它实际上是如何运作的?有什么链接可以引用吗?
任何帮助将不胜感激:)
最佳答案
这就是二进制补码算术的工作原理。
根据 JLS §15.18.2,从 2^31 中减去 1 与 2^31 加 -1 相同。 ,
For both integer and floating-point subtraction, it is always the case that
a-b
produces the same result asa+(-b)
.
还有那个
If an integer addition overflows, then the result is the low-order bits of the mathematical sum as represented in some sufficiently large two's-complement format. If overflow occurs, then the sign of the result is not the same as the sign of the mathematical sum of the two operand values.
现在我们可以用二进制计算 2^31 和 -1 的和。 2^31 是一个 1 后跟 31 个零,其二进制补码为 -2147483648。 -1 的补码是 32,所以我们有:
1000 0000 0000 0000 0000 0000 0000 0000
+1111 1111 1111 1111 1111 1111 1111 1111
正如您所看到的,左侧的最后一位溢出了,但根据第二个摘录,我们忽略了这一点。将所有这些加起来,我们得到:
0111 1111 1111 1111 1111 1111 1111 1111
这是 2147483647
关于java - 当已经溢出时是否可以预测算术结果?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56161565/