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



这是我的代码:

#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);    
}
应用从 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

为什么?这里棘手的部分在哪里?我想不通。不正常?

double中可表示的值在接近零时更密集。您在value == temp时中断循环 - 本质上,当您离目标如此之近以至于通过舍入丢失误差时。这反过来又有效地意味着,当target接近零时,您需要比target具有较大绝对值时更高的精度。

您可能想选择一个比"尾数的最后一点"更合理的精度目标。

最新更新