使用整数运算的平滑算法

Smoothing algorithm using integer arithmetic

以下代码摘自Arduino tutorial on smoothing

int smooth(int data, float filterVal, float smoothedVal) { 

  if (filterVal > 1) {
    filterVal = .99;
  }
  else if (filterVal <= 0) {
    filterVal = 0;
  }

  smoothedVal = (data * (1 - filterVal)) + (smoothedVal  *  filterVal);

  return (int)smoothedVal;
}

以下摘自同一教程的陈述让我开始思考:

This function can easily be rewritten with all-integer math, if you need more speed or want to avoid floats.

事实上我确实想避免浮点数并提高速度,但我想知道:如何将其转换为整数运算? Bit-banging 解决方案是一种奖励 ;o)

一种简单的技术是通过将输入值乘以 10000 并将结果放入 int 中进行缩放,在 int 中进行计算,然后缩放通过除以相同的因子输出回 float

在您的函数中,您还需要使用相同的因子放大所有内容。

因子的选择取决于值的可能范围;你想避免高端溢出和低端不准确。仔细想想,因子决定了小数点的位置:定点,而不是浮点。

因子可以是任何东西,不一定是1001000等,但627也可以。

如果你走这条路,你希望将尽可能多的代码转换为 int,因为上述转换当然也需要时间。

为了说明我的观点,可以是以下内容:

#define FACTOR 10000  // Example value.
int smooth(int data, int filterVal, int smoothedVal)
{ 
    if (filterVal > FACTOR)
    {
        filterVal = FACTOR - 100;
    }
    else if (filterVal <= 0)
    {
        filterVal = 0;
    }

    smoothedVal = (data * (FACTOR - filterVal)) + (smoothedVal * filterVal);

    return smoothedVal;
}

您可以need/want检查溢出,...

//  ------------------------------------------------------------------
//  SMOOTHING WITH INTEGER VARIABLES  (CSHARP)
//  ------------------------------------------------------------------
Int32 Storage;
Int32 SmoothingINT(Int32 NewValue, Int32 Divisor) 
{
    Int32 AvgValue;
    //  ------------------------- Compute the output averaged value 
    AvgValue = Storage / Divisor;
    //  ------------------------- Add to storage the delta (New - Old)
    Storage += NewValue - AvgValue;
    //  -------------------------
    return AvgValue;
}

或者

' -------------------------------------------------------------------
' SMOOTHING WITH INTEGER VARIABLES  (VbNet)
' -------------------------------------------------------------------
Function SmoothingINT(ByVal NewValue As Int32, ByVal Divisor Int32) As Int32
    Dim AvgValue As Int32
    Static Storage As Int32
    ' -------------------------- Compute the output averaged value 
    AvgValue = Storage \ Divisor
    ' -------------------------- Add to storage the delta (New - Old)
    Storage += NewValue - AvgValue
    ' --------------------------
    Return AvgValue 
End Function