我在受限系统中有一个嵌入式C程序,用于读取传感器测量值。我想计算一些事件发生时最后N个传感器读数的运行平均值。我希望计算只使用整数运算(没有浮点)。此外,我没有足够的存储空间来维护所有N个读数,因此我想以某种方式创建一个平均运行总数,并在每次获得新读数时添加到该总数。我看到的一个近似的公式是
avg = ((avg * (n-1)) + currentReading) / n;
当我对此进行编码和测试时,计算出的平均值总是小于我添加所有N个读数并除以N.如何改善这个?
答案 0 :(得分:2)
只需保持运行总数沿着值的数量 - 需要两个整数。最后的简单总和(或任何你想要的)。
答案 1 :(得分:1)
除非您保留最后N个样本,否则无法获得您想要的内容,但您可以使用以下代码进行近似:
avg = ((avg * (n-1)) + currentReading + (n/2)) / n;
这使当前读数的权重在平均值中具有1 / n的显着性。
答案 2 :(得分:0)
OP的代码已经接近但是会受益于舍入分区而不是标准整数分区。所以添加偏见。偏差取决于操作数的符号。
// avg = ((avg * (n-1)) + currentReading) / n;
avg = (avg * (n-1)) + currentReading + bias) / n;
第二个问题是范围之一:(avg * (n-1)) + currentReading
容易溢出。采用更广泛数学的最简单的解决方案。使用更广泛的类型
// Example, depends on system
// avg * (n-1)) + currentReading
1uLL * avg * (n-1)) + currentReading
把它们放在一起:
// avg = ((avg * (n-1)) + currentReading) / n;
int avg, currentReading;
int n; // n > 0
int2x numerator; // int2x some type 2x wide as int, maybe long long
numerator = (int2x)avg * (n-1) + currentReading; // Wider math
int bias = n/2;
if (numerator < 0) bias = -bias;
numerator += bias;
avg = (int) (numerator / n);