6

我有一个应用程序,我在其中跟踪以 µL 为单位的流体体积。我目前正在使用“双”来存储整个系统中的卷,并且在大多数情况下都可以正常工作。然而,当我开始添加和减去大量这些交易量时,各种累积误差开始蔓延。这些错误的幅度非常小,但它们会导致阈值比较问题,突然交易量比预期的小一点,导致验证失败。我知道这是执行累积浮点运算的一个相当普遍的问题,但我想知道如何最好地解决这些问题。我有几个想法:

  1. 我可以用整数替换我所有的双重引用,而是跟踪 nL 中的所有内容。这肯定会解决问题,但这是一个非常具有侵入性的更改。然而,该系统尚未投入生产使用,这意味着现在应用它比以后尝试应用它要容易得多。

  2. 我可以使用十进制而不是双精度。这比更改为整数的侵入性要小,但仍需要进行相当大的更改。

  3. 我可以要求所有体积比较都允许指定的误差容限。这主要是我现在正在做的事情,但它使比较代码更丑陋,并且需要一些代码审查以确保没有人忘记应用该模式。

  4. 我可以在每次计算后执行舍入到指定的容差,以防止错误累积。这使比较更清晰,但现在它在任何有分配的地方都有类似的问题。

对于那些也为这个问题苦苦挣扎的人来说,哪些解决方案最终实施起来最干净?在执行累加计算时,我还应该了解其他问题吗?

4

1 回答 1

2

理想情况下,您希望

  • 使用不受舍入(近似)错误影响的数据类型,并且
  • 四舍五入到正确的小数位数
  • 在正确的时间。

您不需要大范围的双精度浮点数。您可能不想使用整数。它们稍快一些,但使用起来更复杂。使用数字或小数。数字和十进制数据类型不受舍入误差或近似误差的影响。但是你的编程仍然不能马虎或马虎;将数值分配给 double 类型的变量会将问题带回给您。

正确的小数位数正确的时间意味着什么取决于您的应用程序。正确的小数位数有时可能超过您需要存储为最终值的位数。正确的时间会受到中间计算的数量和性质的影响。

有时,人们所说的舍入误差实际上是近似误差。如果您告诉计算机将十进制值r存储在浮点变量或数据库列中,它实际上将存储最接近r的浮点近似值。

FP算术的规范参考

于 2013-02-25T18:12:14.403 回答