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

avd*_*avd 5 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中减去两个非常接近的数字,我将失去精度,但这是第一种方式实现它的唯一原因吗?

Eri*_*hil 8

这不成问题.

首先,请注意0≤a<1,因此平均值中的误差趋于减小,而不是累积.传入的新数据取代了旧的错误.

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

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

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

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