移动项目的平均值

Average for moving items

本文关键字:平均值 项目 移动      更新时间:2023-10-16

我需要制作一个有效的算法来移动整数。

例如,平均 100 个项目。所以随着100个数字的到来,1..100个数字的平均值。由于 101 数字的平均数为 2..101.。由于 102 数字的平均数为 3..102..

我想到了一个解决方案,但我无法想出可以存储最小数量的方法(就像病房之后一样,我必须在微处理器中做,但首先,在 C/C++ 中有效(:

第 1 步:存储 1..100 的数字并取平均值第 2 步:将 1 替换为 101,取平均值:101,2,3...100第 3 步:将 2 替换为 102,取平均值:101,102,3,4...100

但它效率不高,因为我还需要使用更少的除法运算符。

谁能帮我。

您的基本方法很好:使用包含 100 个元素的循环缓冲区。 一个关键的见解:假设您处于"将 2 替换为 102"阶段,2 是 50,而 102 是 70 - 总数将变化 +20 的差值:您只需将新总数除以 100 即可得到新的平均值,而无需再次将所有元素相加。

万一除法太慢,以至于对您的整体表现产生了重大且有问题的影响,那么只有几件事您可以尝试(但要衡量 - 它们实际上可能会减慢您的速度,具体取决于您的确切硬件(:

  • 如果数字范围很小,您可以创建一个从值到值的 100 分之一的查找表(即数组(,然后通过将这些缩放值添加/删除到总数中,您可以直接保持平均值

  • 检查您的系统使用浮点型还是双精度型更快(与直觉相反,有些系统是(

  • 网上有一些奇怪的除以100的"食谱",例如(((((uint32_t)A * (uint32_t)0x47AF) >> 16U) + A) >> 1) >> 6来自 http://embeddedgurus.com/stack-overflow/2009/06/division-of-integers-by-constants/

做移动平均线的最简单方法是使用移动总和。将数字 n[0] 到 n[99] 相加以开始;平均值是这个总和除以 100。对于下一个总和,减去 n[0] 并加上 n[100];再次除以 100 得到平均值。

这最适合整数,因为总和中不会有任何舍入误差;对于浮点数,任何错误都会累积并随着您的进行而变得更糟。

如果使用正整数,则可以通过使窗口大小为 2 的幂来消除除法。使用 128 而不是 100 意味着您可以使用总和的右移 7 除法。

您还可以通过乘以倒数来消除除法。与其除以 100,不如乘以 1/100。如果您正在使用整数,则可能需要使用定点,如果您不小心,也可能会用完位。