棘手的算术还是花招?
Posted
技术标签:
【中文标题】棘手的算术还是花招?【英文标题】:Tricky arithmetic or sleight of hand? 【发布时间】:2010-08-01 05:09:21 【问题描述】:Vincent 通过建议这个函数回答了Fast Arc Cos algorithm。
float arccos(float x)
x = 1 - (x + 1);
return pi * x / 2;
问题是,为什么是x = 1 - (x + 1)
而不是x = -x
?
【问题讨论】:
注意:显然这里提供的解决方案不太正确,但问题仍然存在。 【参考方案1】:仅当 (x + 1) 导致精度损失时,它才会返回不同的结果,即 x 比 1 大或小多个数量级。
但我不认为这是棘手或诡计,我认为这只是错误。
cos(0) = 1 but f(1) = -pi/2
cos(pi/2) = 0 but f(0) = 0
cos(pi) = -1 but f(-1) = pi/2
其中f(x)
是Vincent 的arccos
实现。它们都偏离pi/2
,至少这三个点正确的线性近似是
g(x) = (1 - x) * pi / 2
【讨论】:
我仍然没有得到精度部分的损失,你能提供一个例子吗? @David,试试1.0 - (1.0 + 1e-16)
vs -(1e-16)
看一下acos 的图表 - 更好的线性近似值(基于 x=0 处的切线)将是 g(x) = pi/2 - x
,它非常准确,除非 x 接近-1 或 1
@BlueRaja:我同意简单地连接这三个点并不是最优的(使用 x=0 处的切线也不能最小化均方误差),只是它是最简单的近似这可能有用。文森特给的原件肯定没用。【参考方案2】:
我不会立即看到细节,但想想当 x 从任一侧接近 1 或 -1 时会发生什么,并考虑舍入误差。
【讨论】:
【参考方案3】:加法会导致两个数字都被归一化(在这种情况下,与 x 相关)。 IIRC,在 Knuth 的第 2 卷关于浮点运算的章节中,您甚至可以看到像 x+0 这样的表达式。
【讨论】:
以上是关于棘手的算术还是花招?的主要内容,如果未能解决你的问题,请参考以下文章