使用整数算法计算C中N个整数的平均值,而不保留N个值

时间:2017-02-19 16:38:54

标签: c

我在受限系统中有一个嵌入式C程序,用于读取传感器测量值。我想计算一些事件发生时最后N个传感器读数的运行平均值。我希望计算只使用整数运算(没有浮点)。此外,我没有足够的存储空间来维护所有N个读数,因此我想以某种方式创建一个平均运行总数,并在每次获得新读数时添加到该总数。我看到的一个近似的公式是

avg = ((avg * (n-1)) + currentReading) / n;

当我对此进行编码和测试时,计算出的平均值总是小于我添加所有N个读数并除以N.如何改善这个?

3 个答案:

答案 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);