一般公式为:
Davg, k = a * Davg, k – 1 + (1 – a) * Dk – 1/H2>
但是在实现它的时候,如果我这样做,只是为了保存一个浮点运算,
Davg, k = a * ( Davg, k – 1 - Dk – 1 ) + Dk – 1
它对精度有多大影响?或者这样做是完全错误的。我知道我可能对只保存一个 FP op 有点偏执,我已经准备好以理论上的方式实现它,但我仍然想了解这一点。无论细节如何,您可以提供的示例都很棒。谢谢。
编辑: 当然我知道在第二种方式中,如果我在 FP 中减去两个非常接近的数字,我会失去精度,但这是第一种方式实现它的唯一原因吗?
最佳答案
这不是问题。
首先,请注意 0 ≤ a < 1,因此平均值中的误差往往会减少,而不是累积。传入的新数据会取代旧错误。
减去相似大小(和相同符号)的 float 不会失去绝对精度。 (你写了“精度”,但精度是表示值的精度,例如 double
类型的宽度,并且不会随着减法而改变。)减去相似大小的数字可能会导致相对误差的增加:由于结果越小,误差相对越大。但是,中间值的相对误差无关紧要。
事实上,减去两个数,每个数都等于或超过另一个数的一半,没有错误:正确的数学结果是可以精确表示的(Sterbenz 引理)。
因此,后一个操作序列中的减法很可能是准确的或低误差的,具体取决于值的波动程度。然后乘法和加法有通常的舍入误差,除非同时有正值和负值,否则它们不是特别令人担忧,这会在平均值接近零时导致较大的相对误差。如果可以使用融合乘加运算(请参阅 fma
中的 <tgmath.h>
),则可以消除乘法运算中的错误。
在前面的操作序列中,对1-a
的求值如果 a
将是准确的至少是 ½。剩下两次乘法和一次加法。这往往会比后一个序列有稍微大的错误,但可能不足以引起注意。和以前一样,旧错误会趋于减少。
关于c - 最小化指数移动平均中的浮点不准确性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16864630/