要给出分数 f
两个变量 a
和 b
之间的线性插值,我目前正在使用此代码:
float lerp(float a, float b, float f)
{
return (a * (1.0 - f)) + (b * f);
}
我认为这可能是一种更有效的方法 . 我使用的是没有FPU的微控制器,因此浮点运算是在软件中完成的 . 它们相当快,但它仍然可以添加或增加100个周期 .
有什么建议?
注:为了清楚起见,在上面的代码中,我们可以省略将 1.0
指定为显式浮点文字 .
5 回答
如果您希望最终结果为整数,那么对输入使用整数可能会更快 .
这会做两次演员和一次浮动 . 如果演员阵容比平台上的浮点数加/减快,并且整数答案对您有用,这可能是一个合理的选择 .
假设浮点数学是可用的,OP的算法是一个很好的算法,并且由于精度损失,当
a
和b
在幅度上有显着差异时,总是优于备选a + f * (b - a)
.例如:
在该示例中,假设32位浮点数
lint1(1.0e20, 1.0, 1.0)
将正确返回1.0,而lint2
将错误地返回0.0 .当操作数的大小差异很大时,大多数精度损失在加法和减法运算符中 . 在上面的例子中,罪魁祸首是
b - a
中的减法,以及a + f * (b - a)
中的加法 . 由于组件在加法之前完全相乘,因此OP的算法不会受此影响 .对于a = 1e20,b = 1的情况,这是不同结果的示例 . 测试程序:
输出,略微调整格式:
如果您使用的是没有FPU的微控制器,那么浮点将非常昂贵 . 对于浮点运算,可能容易慢20倍 . 最快的解决方案是使用整数进行所有数学运算 .
固定二进制点(http://blog.credland.net/2013/09/binary-fixed-point-explanation.html?q=fixed+binary+point)之后的位数是:XY_TABLE_FRAC_BITS .
这是我使用的一个功能:
内联功能应该是约 . 10-20个周期 .
如果你有一个32位微控制器,你将能够使用更大的整数,在不影响性能的情况下获得更大的数字或更高的精度 . 该功能用于16位系统 .
如果你最好不要使用浮点数,而是使用fixed-point arithmetic .
不考虑精度的差异,该表达式相当于
这是2次加法/减法和1次乘法,而不是2次加法/减法和2次乘法 .