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

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

一般公式为:

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/

相关文章:

floating-point - 一个 float 可以在给定范围内表示多少个值?

python - 为什么我的程序在执行看似无限循环时会停止?

python - 欧拉-马歇罗尼常数

c - 如何确定要使用哪个 SOC 或 SDK 板?

c++ - 为什么我在 Linux 上看不到 SOCK_SEQPACKET 的 MSG_EOR?

c - 我应该更正哪个指针语句以避免段错误

c - 当我使用 float 时,如果我限制范围,我会失去精度吗?

objective-c - 如何在 Objective-C 中传递 C 风格的矩阵

python - 如何获得 [-2.3,-2.2,...] 的列表?

c# - 为什么添加 float 会根据其执行方式产生不同的结果