Vincent通過暗示該功能回答了Fast Arc Cos algorithm。棘手的算術或手術嗎?
float arccos(float x)
{
x = 1 - (x + 1);
return pi * x/2;
}
的問題是,爲什麼x = 1 - (x + 1)
而不是x = -x
?
Vincent通過暗示該功能回答了Fast Arc Cos algorithm。棘手的算術或手術嗎?
float arccos(float x)
{
x = 1 - (x + 1);
return pi * x/2;
}
的問題是,爲什麼x = 1 - (x + 1)
而不是x = -x
?
只有當(x + 1)導致精度損失時,它纔會返回不同的結果,也就是說x的數量級大於或小於一個數量級。
但我不認爲這是棘手或巧妙的手法的,我認爲這只是普通錯誤。
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)
是文森特的arccos
實現。他們都是關閉的pi/2
,線性近似是得到至少這三點正確的是
g(x) = (1 - x) * pi/2
我仍然不知道精密零件的損失,請您舉個例子嗎? – 2010-08-01 05:48:22
@David,試試'1.0 - (1.0 + 1e-16)'vs' - (1e-16)' – Anycorn 2010-08-01 05:56:52
看一看[acos]的圖形(http://www.mathworks.com/access/helpdesk /help/techdoc/ref/acos.gif) - 一個更好的線性近似(基於x = 0處的切線)將是'g(x)= pi/2 - x',除非x接近-1或1 – 2010-08-02 20:38:40
我看不到的細節瞬間,但想想爲x發生了什麼接近1或-1從任何一方,並考慮舍入誤差。
加法導致兩個數字都歸一化(在這種情況下,與x有關)。 IIRC,在Knuth的第2卷的關於浮點運算的章節中,您甚至可以看到像x + 0這樣的表達式。
**注意:**顯然這裏提供的解決方案並不完全正確,但問題仍然存在。 – 2010-08-01 05:36:16