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,165
  • 12
  • 42
  • 51

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
  • 277,958
  • 43
  • 419
  • 720
  • 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
  • 110,348
  • 25
  • 193
  • 263
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
  • 24,186
  • 3
  • 55
  • 65