为什么在一种情况下乘以大数会得出错误的结果?
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
。
这似乎很简单,但我没有任何答案。 当我写:
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
。