当它已经溢出时,可以预测算术结果吗?

时间:2019-05-16 05:46:47

标签: java

假设我们有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

但是我发现没有规范可以验证我的猜测,有一些吗?

来自Integer overflow wiki

  

当算术运算得出的结果大于一个N位整数的最大值时,溢出会将结果减小为2的N次幂模,仅保留结果的最低有效位并有效地导致换行周围。

如果我的猜测是完全错误的,那么它实际上是如何工作的?我可以参考任何链接吗?

任何帮助将不胜感激:)

1 个答案:

答案 0 :(得分:1)

这就是二进制补码算术的工作原理。

根据JLS §15.18.2,从2 ^ 31中减去1等于2 ^ 31加-1,

  

对于整数和浮点减法,总是这样   a-b产生的结果与a+(-b)相同。

还有

  

如果整数加法溢出,则结果为低阶   数学和的位数,以足够大的幅度表示   二进制补码格式。如果发生溢出,则指示   结果与两者的数学和的符号不同   操作数值。

现在,我们可以计算二进制值2 ^ 31和-1的总和。 2 ^ 31是一个1,后跟31个零,即2的补码中的-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