为什么在一种情况下乘以大数会得出错误的结果?

Why in one case multiplying big numbers gives a wrong result?

这似乎很简单,但我没有任何答案。 当我写:

 System.out.println (100 * 1000 * 10000 * 100000);
 System.out.println (100 * 1000 * 10000 * 100000.0);

它 return 这些值:

276447232
1.0E14

我了解到这与某些数据类型的最大值有关。但我只是想要一个明确的答案,说明为什么它 return 是两个方程的这些精确值。如果有人能向我解释一下,我将不胜感激。

第一个 return 与 int 数据类型的最大值不匹配,这就是我感到困惑的原因。第二个 return 我假设是双精度或浮点值,但我不确定。

在表达式中

System.out.println (100 * 1000 * 10000 * 100000);

参数是一个 int,结果超过了 int 允许的最大值,即 2147483647。这就是我们所说的溢出。根据 Java Language Specification

If an integer multiplication overflows, then the result is the low-order bits of the mathematical product as represented in some sufficiently large two's-complement format.

取一个数的N个低位相当于计算这个数除以2^N的余数。在我们的例子中,N=32 因为 int 存储在 32 位上。这就是为什么 Jon Skeet 回答说

100000000000000 % (2^32) is 276447232.

在表达式中

System.out.println (100 * 1000 * 10000 * 100000.0);

三个第一个因数 100 * 1000 * 10000 的乘积得出 1_000_000_000,小于最大 int 值。最后一个乘法导致 Binary Numeric Promotion,这意味着,在这种情况下,1_000_000_000 被转换(提升)为 double,然后乘以 100000.0