0

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

例如,平均 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

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

谁能帮帮我。

4

2 回答 2

2

您的基本方法很好:使用具有 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/

于 2013-07-08T02:16:55.610 回答
1

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

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

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

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

于 2013-07-08T03:05:32.703 回答