最小化指数移动平均线的浮点不准确性

时间:2013-05-31 19:35:47

标签: c floating-point floating-accuracy floating-point-precision

通常,公式为:

D avg,k = a * D avg,k - 1 +(1 - a)* D k - 1

但在实现它时,如果我这样做,只是为了保存一个浮点运算,

D avg,k = a *(D avg,k - 1 - D k - 1 )+ D k - 1

它对精度有多大影响?或者这样做是非常错误的。我知道我可能一直偏执只是保存一个FP操作,我准备以理论方式实现它,但我仍然想了解这一点。无论细节如何,您可以提供的示例都很棒。感谢。

编辑: 当然我理解,在第二种方式中,如果我在FP中减去两个非常接近的数字,我将失去精度,但这是第一种方式实现它的唯一原因吗?

1 个答案:

答案 0 :(得分:8)

这不是问题。

首先,注意0≤a<0。 1,所以平均值的误差往往会减少,而不会累积。传入的新数据取代了旧错误。

减去相似幅度(和相同符号)的浮点数不会失去绝对精度。 (您写的是“精度”,但精度是表示值的精细度,例如double类型的宽度,并且不会随减法而变化。)减去相似幅度的数字可能会导致增加相对误差:由于结果较小,误差相对较大。但是,中间值的相对误差无关紧要。

事实上,减去两个数字,每个数字等于或超过另一个数字的一​​半,没有错误:正确的数学结果是完全可表示的(Sterbenz'Lemma)。

因此,后一个操作序列中的减法可能是精确的或低误差的,这取决于值波动的程度。然后乘法和加法具有通常的舍入误差,除非存在正值和负值,否则它们不会特别令人担忧,当平均值接近零时,这可能导致较大的相对误差。如果可以使用融合乘法 - 加法运算(请参阅fma中的<tgmath.h>),则可以消除乘法中的误差。

在前一个操作序列中,如果1-a至少为1/2,则a的评估将是准确的。这留下了两次乘法和一次加法。这将比后一个序列具有更大的误差,但可能不足以引起注意。和以前一样,旧的错误往往会减少。