使用整数运算的平滑算法
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
。
在您的函数中,您还需要使用相同的因子放大所有内容。
因子的选择取决于值的可能范围;你想避免高端溢出和低端不准确。仔细想想,因子决定了小数点的位置:定点,而不是浮点。
因子可以是任何东西,不一定是100
、1000
等,但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
以下代码摘自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
。
在您的函数中,您还需要使用相同的因子放大所有内容。
因子的选择取决于值的可能范围;你想避免高端溢出和低端不准确。仔细想想,因子决定了小数点的位置:定点,而不是浮点。
因子可以是任何东西,不一定是100
、1000
等,但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