【问题标题】:Ordering operation to maximize double precision排序操作以最大化双精度
【发布时间】:2013-06-15 06:20:49
【问题描述】:

我正在开发一些工具来计算在最坏情况下可以接近1e-25 的数字,并在 Java 中将它们一起比较。我显然使用的是双精度。

我在another answer 中读到,我不应该期望超过1e-151e-17 的精度,this other question 涉及在以“更好”的顺序排序操作时获得更好的精度。

哪个双精度运算更热衷于在此过程中降低精度?我应该尝试使用尽可能大的数字还是尽可能小的数字?先除法再乘法?

我宁愿不使用BigDecimal 类或等效类,因为代码已经够慢了;)(当然,除非它们不会对速度造成太大影响)。

任何信息将不胜感激!

编辑:数字的绝对值“小”(1e-25)这一事实并不重要,因为 double 可以下降到 1e-324。但重要的是,当它们非常相似时(都在 1e-25 中),我必须比较,比如说 4.64563824048517606458e-21 到 4.64563824048517606472e-21(差异是第 19 位和第 20 位)。当计算这些数字时,差异是如此之小,以至于我可能会遇到“舍入误差”,其中余数被随机数填充。

问题是:“如何对计算进行排序以使这种精度损失最小化?”。它可能在乘法之前先做除法,或者先做加法。

【问题讨论】:

  • 谢谢,我会看看并回复你,但听起来很有希望。
  • 关于取消的部分是我要找的!您可以将其发布为答案以便我接受吗?
  • 很高兴它有帮助。欢迎您回答自己的问题并接受自己的答案。如果以后的用户觉得它有帮助,他们可以对您的问题和答案都投赞成票。

标签: java double precision arbitrary-precision


【解决方案1】:

如果获得正确答案很重要,您应该使用 BigDecimal。它比 double 慢,但在大多数情况下它已经足够快了。我想不出在很多情况下,你用如此小的数字进行大量计算,而答案是否正确并不重要——至少对于 Java。

如果这是一个超级性能敏感的应用程序,我会考虑使用不同的语言。

【讨论】:

  • 确实如此。我只是将我的结果与另一个应用程序进行比较,它们匹配直到我似乎达到双倍精度。如果真的是这样,我觉得停在那里就足够了,但是如果有办法重新排序计算,这样我就不会失去(太多)精度(例如,先做除法?),我想这样做。
【解决方案2】:

感谢@John 指出关于浮点运算的very complete article

事实证明,当需要精度时,应重新排序运算,并调整公式以避免精度损失,如Cancellation 章节中所述:当比较彼此非常接近的数字时(是我的情况),可能会发生“灾难性的取消”,从而导致精度的巨大损失。通常,根据您对操作数值的先验知识重新编写公式或重新排序运算可以提高微积分的准确性。

我会从这篇文章中记住的是:

  • 在减去两个几乎相同的量时要小心
  • 尝试重新安排操作以避免灾难性取消

对于后一种情况,请记住计算 (x - y) * (x + y) 提供的结果比 x * x - y * y 更准确。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-03-17
    • 1970-01-01
    • 2019-02-06
    • 1970-01-01
    • 1970-01-01
    • 2015-06-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多