【问题标题】:Smoothing algorithm using integer arithmetic使用整数运算的平滑算法
【发布时间】:2015-07-29 17:49:01
【问题描述】:

以下代码取自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;
}

以下语句来自同一个教程,让我思考:

如果您需要更快的速度或想要避免浮点数,可以使用全整数数学轻松重写此函数。

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

【问题讨论】:

  • 有理数?
  • 可能是fixed point math 在您的用例中派上用场。
  • @Aderis 乘以和除以 2 的幂通常更快,因为它可以用移位代替。
  • 过滤算法有很多种,针对不同的需求有不同的响应。该函数返回int 所以我想知道它的输入值float smoothedVal 来自哪里。
  • @heltonbiker 嗯,不仅仅是链接的答案。我在我的平板电脑上,编写包含大量代码的答案很困难。让我们看看,也许我明天可以对文章中描述的内容进行简要汇编。你也可以自己写一个,没关系。

标签: c++ c arduino integer bit-manipulation


【解决方案1】:

一种简单的技术是通过将输入值乘以 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;
}

您可能需要/想要检查溢出,...

【讨论】:

    【解决方案2】:
    //  ------------------------------------------------------------------
    //  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
    

    【讨论】:

      猜你喜欢
      • 2012-10-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-02-17
      相关资源
      最近更新 更多