为什么从超出限制的 int 中滥用 1 而不是 1.0 会影响我们在将其转换为双精度时获得的值



这是我将使用的代码...

public class foo {

public static void main(String [] args){
int a = (int) Math.pow(2, 30);
double d = (a + a - 1.0);
double f = (a + a - 1);
System.out.println(d);
System.out.println(f);
}

}

输出为 -2.147483649E9和 2.147483647E9。

我不明白为什么要打印出这些值。我的理解是 a + a 将超过 int 的限制,因此将转换为负数,但是,f 是正数。我希望两者都是负数,但 f 将是小数,而 d 由于整数除法而是一个点为 0 的双精度。

在第一种情况下,a + a溢出到Integer.MIN_VALUE,然后你切换到一个double上下文,-1.0给出一个负数(Integer.MIN_VALUE - 1),因为一个double可以容纳一个小于Integer.MIN_VALUE的数字。

在第二个示例中,您停留在int上下文中,这意味着a + a溢出到Integer.MIN_VALUE,然后从该下溢中减去 1 并带您回到Integer.MAX_VALUE

一步一步地拆开它,就会发现答案。

首先,我们观察到a + a == Integer.MIN_VALUEIdeone.com演示

接下来,如果计算表达式a + a - 1.0,则从左到右计算,即相当于(a + a) - 1.0,相当于Integer.MIN_VALUE - 1.0。由于右手边是doubleInteger.MIN_VALUE也转换为double,结果为负数。

最后,如果计算表达式a + a - 1,则等效于Integer.MIN_VALUE - 1。整个操作在int空间中用环算术完成,从MIN_VALUE的子1计算到MAX_VALUE

相关内容

最新更新