干净地处理舍入/累加错误

本文关键字:错误 舍入 处理 | 更新日期: 2023-09-27 18:00:56

我有一个应用程序,用于跟踪以µL为单位的流体体积。我目前在整个系统中使用"double"来存储卷,在大多数情况下,这都很好。然而,当我开始对这些体积进行大量加减运算时,各种累积误差开始悄悄出现。这些误差的幅度很小,但它们会导致阈值比较出现问题,体积突然比预期小了一小部分,导致验证失败。我知道这是执行累积浮点运算时相当常见的问题,但我想知道如何最好地解决这些问题。我有几个想法:

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

  2. 我可以用小数代替双精度。这比更改为整数的侵入性更小,但仍然需要相当大的更改。

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

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

对于那些也在这个问题上挣扎的人来说,什么解决方案最终是最干净的?在进行累积计算时,我还应该了解其他问题吗?

干净地处理舍入/累加错误

理想情况下,您希望

  • 使用不受舍入(近似(误差影响的数据类型,以及
  • 四舍五入到小数位数
  • 在正确的时间

你不需要大范围的双精度浮子。您可能不想使用整数。它们稍微快一点,但使用起来更复杂。使用数字或十进制。数值和十进制数据类型不受舍入误差或近似误差的影响。但是你在编程中仍然不能粗心大意;为double类型的变量指定一个数值会让你重新想到这个问题。

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

有时,人们所说的舍入误差实际上是近似误差存储在浮点变量或数据库列中,它实际上会存储最接近r的浮点近似值。

FP算术的规范参考