【问题标题】:Java very small number arithmetic operationJava极小数算术运算
【发布时间】:2014-04-06 12:45:29
【问题描述】:

表达式的结果:2.227E-19-1.0+1.0 将是 0.0

我怎样才能得到 2.227E-19 的结果?

我有一个表情

a-b+1

  • a 始终是一个非常小的数字。
  • b 可能接近 1.0

当一个非常小的数字与一个大数字运算时如何保持准确性?

【问题讨论】:

  • 有什么问题?你得到什么? ab 的值是多少?
  • + (1.0 - b)。但这是人为的:IEEE double 有 16 位精度,所以 b 和 1 之间的最小变化大于 a 的大小——你基本上已经失去了所有的精度。

标签: java numbers arithmetic-expressions


【解决方案1】:

只需使用double 来存储结果。它具有足够的精度来进行此计算。

【讨论】:

  • 我不认为这是真的,用给定的值测试它会导致 0 即使是双精度。
【解决方案2】:

如果您事先知道哪些操作数可以很小,则可以重新排序操作:

-b + 1 + a

这样会先计算a之前的部分,两边(-b+1a)的量级大致相同,导致浮点问题更少。

这是The Java™ Tutorials的相关部分:

同一行的运算符具有相同的优先级。当相同优先级的运算符出现在同一个表达式中时,必须有一个规则来控制首先计算哪个。除了赋值运算符之外的所有二元运算符都是从左到右计算的;

【讨论】:

  • 以上产生了更明显的精度,但没有更高的精度。
  • 我不确定您的确切意思;至少对于b=1 的情况,这种方法可以防止a 被取消,据我所知,这是主要问题。
  • 如果b真的是1 - 1.0E-17,如果以更高的精度计算,那么总体结果将与2.227E-19有很大不同。重新排列顺序以产生明显更精确的结果并不会产生更准确的结果。
【解决方案3】:

或者使用具有足够规模的 BigDecimal。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-01
    相关资源
    最近更新 更多