1

在java中,以下表达式结果为

new Double(1.0E22) + new Double(3.0E22)  = 4.0E22

new Double(1.0E22) + new Double(4.0E22)  = 4.9999999999999996E22

我期待它是5.0E22。双倍极限是1.7976931348623157E308。感谢你的帮助。我机器的架构是 x64,JVM 也是 64 位的。

4

2 回答 2

4

欢迎来到浮点单元的星球。不幸的是,在现实世界中,您必须放弃一些精度才能获得速度和表示的广度。你无法避免:double只是一个近似的表示。实际上,您不能以有限的精度表示数字。尽管如此,这是一个很好的近似值:小于 0.00000000001% 的误差。double这与上限无关,而与 CPU 限制无关,请尝试使用 Python 进行更多数学运算:

>>> 4.9999999999999996 / 5.
1.0
>>> 5. - 4.9999999999999996
0.0

看?作为旁注,永远不要检查 上的相等性double,使用近似相等:

if ((a - b) < EPSILON)

哪里EPSILON是一个很小的值。可能 Java 库有更合适的东西,但你明白了。

如果您对某些理论感兴趣,浮点运算的标准是IEEE754

于 2013-05-08T13:26:48.317 回答
0

有几种方法可以减少浮点错误,例如pairwise summationKahan summation,但是这些都不能帮助你精确地表示像 5.0E22 这样的数字 - 正如 Stefano Sanfilippo 在他的回答中所说的那样,这是由于什么的限制您可以使用浮点表示,而不是用于实现答案的算法的问题。要表示 5.0E22,您应该使用BigDecimal或使用具有Rational数据类型的库,例如JScience

于 2013-05-08T14:03:41.930 回答