3

Vincent answered Fast Arc Cos algorithm by suggesting this function.

float arccos(float x) 
{ 
    x = 1 - (x + 1); 
    return pi * x / 2; 
} 

The question is, why x = 1 - (x + 1) and not x = -x?

Community
  • 1
  • 1
David Weng
  • 4,085
  • 12
  • 40
  • 50

3 Answers3

3

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
Ben Voigt
  • 269,602
  • 39
  • 394
  • 697
  • I don't still get loss of precision part, could you please provide an example? – David Weng Aug 01 '10 at 05:48
  • @David, try `1.0 - (1.0 + 1e-16)` vs `-(1e-16)` – Anycorn Aug 01 '10 at 05:56
  • Take a look at the graph of [acos](http://www.mathworks.com/access/helpdesk/help/techdoc/ref/acos.gif) - a better linear approximation (based on the tangent line at x=0) would be `g(x) = pi/2 - x`, which is pretty accurate except when x is close to -1 or 1 – BlueRaja - Danny Pflughoeft Aug 02 '10 at 20:38
  • @BlueRaja: I agree that simply connecting these three points isn't optimal (and neither does using the tangent line at x=0 minimize the mean-square error), just that it's the most trivial approximation that could possibly be useful. The original one given by Vincent definitely was not useful. – Ben Voigt Aug 03 '10 at 02:13
0

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.

Charlie Martin
  • 107,118
  • 23
  • 189
  • 257
0

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.

zvrba
  • 23,738
  • 3
  • 53
  • 65