diff options
author | Eric Andersen <andersen@codepoet.org> | 2001-11-22 00:15:59 +0000 |
---|---|---|
committer | Eric Andersen <andersen@codepoet.org> | 2001-11-22 00:15:59 +0000 |
commit | c117dd5fb183afb1a4790a6f6110d88704be6bf8 (patch) | |
tree | 13ce27b066f424accc986a0f2c915c144d332861 /libm/double | |
parent | ee185898f61c50ad0b174b45a58c38054571a0b3 (diff) |
Seems we were lacking an acos() implementation
Diffstat (limited to 'libm/double')
-rw-r--r-- | libm/double/acos.c | 58 |
1 files changed, 58 insertions, 0 deletions
diff --git a/libm/double/acos.c b/libm/double/acos.c new file mode 100644 index 000000000..60f61dc98 --- /dev/null +++ b/libm/double/acos.c @@ -0,0 +1,58 @@ +/* acos() + * + * Inverse circular cosine + * + * + * + * SYNOPSIS: + * + * double x, y, acos(); + * + * y = acos( x ); + * + * + * + * DESCRIPTION: + * + * Returns radian angle between 0 and pi whose cosine + * is x. + * + * Analytically, acos(x) = pi/2 - asin(x). However if |x| is + * near 1, there is cancellation error in subtracting asin(x) + * from pi/2. Hence if x < -0.5, + * + * acos(x) = pi - 2.0 * asin( sqrt((1+x)/2) ); + * + * or if x > +0.5, + * + * acos(x) = 2.0 * asin( sqrt((1-x)/2) ). + * + * + * ACCURACY: + * + * Relative error: + * arithmetic domain # trials peak rms + * DEC -1, 1 50000 3.3e-17 8.2e-18 + * IEEE -1, 1 10^6 2.2e-16 6.5e-17 + * + * + * ERROR MESSAGES: + * + * message condition value returned + * asin domain |x| > 1 NAN + */ + +#define __USE_BSD +#include <math.h> + +double acos(double x) +{ + if (x < -0.5) { + return (M_PI - 2.0 * asin( sqrt((1+x)/2) )); + } + if (x > 0.5) { + return (2.0 * asin( sqrt((1-x)/2) )); + } + + return(M_PI_2 - asin(x)); +} |