为什么将指数移动平均值应用于0.0更慢?

时间:2018-01-26 15:01:28

标签: c++ algorithm moving-average

这是my code

#include <math.h> 
#include <iostream>

using namespace std;

inline void Task(double start, double target) {
    double a0 = 0.0101252;
    double z = start;

    double value = -1.0;
    double temp = 0.0;
    int counter = 0;    
    while (value != temp) {
        temp = value;

        // exponential moving average
        z += a0 * (target - z);
        value = z;

        counter++;
    }

    cout << "start: " << start << " | target: " << target << " | iterations: " << counter << std::endl;    
}

int main() 
{   
    Task(0.0, 0.01);
    Task(0.01, 0.0);

    Task(0.01, 0.02);
    Task(0.02, 0.01);    
}

Exponential Moving Average应用于0.1到0.2(或从0.2到0.1或0.0到0.1)会导致大约3100次迭代:

start: 0 | target: 0.01 | iterations: 3173
start: 0.01 | target: 0.02 | iterations: 3105
start: 0.02 | target: 0.01 | iterations: 3173

相反,如果我去0.0,它的东西比迭代方面贵25倍:

start: 0.01 | target: 0 | iterations: 72305

为什么呢?这里的棘手部分在哪里?我无法弄明白。非规格化?

1 个答案:

答案 0 :(得分:3)

double中可表示的值在零附近更密集。你在value == temp时打破循环 - 实质上,当你如此接近目标时,错误会通过舍入而丢失。反过来,这有效地意味着当target接近零时要求的精度要高于target具有大绝对值时的精确度。

您可能希望选择比“尾数的最后一位”更合理的精确目标。