Tricky arithmetic or sleight of hand?
Vincent answered Fast Arc Cos algorithm by suggesting this function.
float arccos(float x)
{
x = 1 - 开发者_JAVA技巧(x + 1);
return pi * x / 2;
}
The question is, why x = 1 - (x + 1)
and not x = -x
?
It returns a different result only when (x + 1) causes a loss of precision, that is, x is many orders of magnitude larger or smaller than one.
But I don't think this is tricky or sleight of hand, I think it's just plain wrong.
cos(0) = 1 but f(1) = -pi/2
cos(pi/2) = 0 but f(0) = 0
cos(pi) = -1 but f(-1) = pi/2
where f(x)
is Vincent's arccos
implementation. All of them are off by pi/2
, a linear approximation that gets at least these three points correct would be
g(x) = (1 - x) * pi / 2
I don't see the details instantly, but think about what happens as x approaches 1 or -1 from either side, and consider roundoff error.
Addition causes that both numbers are normalized (in this case, relevant for x). IIRC, in Knuth's volume 2, in the chapter on floating-point arithmetic, you can even see an expression like x+0.
精彩评论