lerp
的实现方法:float lerp(float a, float b, float f)
{
return (a * (1.0 - f)) + (b * f);
}
另一个用户提出了这个 lerp
的实现:
float lerp(float a, float b, float f)
{
return a + f * (b - a);
}
显然,由于浮点精度损失,后一种实现方式较差。
我随后在 维基百科 上查看,它说针对前一种实现方式:
// Precise method, which guarantees v = v1 when t = 1. This method is monotonic only when v0 * v1 < 0.
// Lerping between same values might not produce the same value
并且对于后者:
// Imprecise method, which does not guarantee v = v1 when t = 1, due to floating-point arithmetic error.
// This method is monotonic. This form may be used when the hardware has a native fused multiply-add instruction.
这让我有几个问题:
Wikipedia states that "Lerping between same values might not produce the same value" I thought that except for floating point accuracy the functions are identical. Isn't
(a * (1.0 - f)) + (b * f)=a + f * (b - a)
a mathematical identity?
If not what would be values that would give different results in both functions?
What does Wikipedia mean by monotonic? Why is one implementation monotonic while the other is not?
Are there other common implementations of
lerp
?
编辑: 如果后一种实现在没有真正更快的情况下遭受浮点精度问题,那么它为什么存在呢?
x*1.0 == x
、x+0.0==x
,以及对于有限的x
:x*0.0 == 0.0
和x-x == 0.0
(我忽略了+0.0
和-0.0
之间的差异)。 - chtz