Cygwin: mmap: allow remapping part of an existing anonymous mapping
[newlib-cygwin.git] / newlib / libm / mathfp / s_asine.c
blob9e9073d1f09654885e51fb36c139e6bc3d7e0cc5
2 /* @(#)z_asine.c 1.0 98/08/13 */
3 /******************************************************************
4 * The following routines are coded directly from the algorithms
5 * and coefficients given in "Software Manual for the Elementary
6 * Functions" by William J. Cody, Jr. and William Waite, Prentice
7 * Hall, 1980.
8 ******************************************************************/
11 FUNCTION
12 <<asin>>, <<asinf>>, <<acos>>, <<acosf>>, <<asine>>, <<asinef>>---arc sine or cosine
14 INDEX
15 asin
16 INDEX
17 asinf
18 INDEX
19 acos
20 INDEX
21 acosf
22 INDEX
23 asine
24 INDEX
25 asinef
27 SYNOPSIS
28 #include <math.h>
29 double asine(double <[x]>);
30 float asinef(float <[x]>);
31 double asin(double <[x]>);
32 float asinf(float <[x]>);
33 double acos(double <[x]>);
34 float acosf(float <[x]>);
36 DESCRIPTION
38 <<asin>> computes the inverse sine or cosine of the argument <[x]>.
39 Arguments to <<asin>> and <<acos>> must be in the range @minus{}1 to 1.
41 <<asinf>> and <<acosf>> are identical to <<asin>> and <<acos>>, other
42 than taking and returning floats.
44 RETURNS
45 @ifnottex
46 <<asin>> and <<acos>> return values in radians, in the range of -pi/2 to pi/2.
47 @end ifnottex
48 @tex
49 <<asin>> and <<acos>> return values in radians, in the range of $-\pi/2$ to $\pi/2$.
50 @end tex
52 If <[x]> is not in the range @minus{}1 to 1, <<asin>> and <<asinf>>
53 return NaN (not a number), set the global variable <<errno>> to
54 <<EDOM>>, and issue a <<DOMAIN error>> message.
58 /******************************************************************
59 * Arcsine
61 * Input:
62 * x - floating point value
63 * acosine - indicates acos calculation
65 * Output:
66 * Arcsine of x.
68 * Description:
69 * This routine calculates arcsine / arccosine.
71 *****************************************************************/
73 #include "fdlibm.h"
74 #include "zmath.h"
76 #ifndef _DOUBLE_IS_32BITS
78 static const double p[] = { -0.27368494524164255994e+2,
79 0.57208227877891731407e+2,
80 -0.39688862997404877339e+2,
81 0.10152522233806463645e+2,
82 -0.69674573447350646411 };
83 static const double q[] = { -0.16421096714498560795e+3,
84 0.41714430248260412556e+3,
85 -0.38186303361750149284e+3,
86 0.15095270841030604719e+3,
87 -0.23823859153670238830e+2 };
88 static const double a[] = { 0.0, 0.78539816339744830962 };
89 static const double b[] = { 1.57079632679489661923, 0.78539816339744830962 };
91 double
92 asine (double x,
93 int acosine)
95 int flag, i;
96 int branch = 0;
97 double g, res, R, P, Q, y;
99 /* Check for special values. */
100 i = numtest (x);
101 if (i == NAN || i == INF)
103 errno = EDOM;
104 if (i == NAN)
105 return (x);
106 else
107 return (z_infinity.d);
110 y = fabs (x);
111 flag = acosine;
113 if (y > 0.5)
115 i = 1 - flag;
117 /* Check for range error. */
118 if (y > 1.0)
120 errno = ERANGE;
121 return (z_notanum.d);
124 g = (1 - y) / 2.0;
125 y = -2 * sqrt (g);
126 branch = 1;
128 else
130 i = flag;
131 if (y < z_rooteps)
132 res = y;
133 else
134 g = y * y;
137 if (y >= z_rooteps || branch == 1)
139 /* Calculate the Taylor series. */
140 P = ((((p[4] * g + p[3]) * g + p[2]) * g + p[1]) * g + p[0]) * g;
141 Q = ((((g + q[4]) * g + q[3]) * g + q[2]) * g + q[1]) * g + q[0];
142 R = P / Q;
144 res = y + y * R;
147 /* Calculate asine or acose. */
148 if (flag == 0)
150 res = (a[i] + res) + a[i];
151 if (x < 0.0)
152 res = -res;
154 else
156 if (x < 0.0)
157 res = (b[i] + res) + b[i];
158 else
159 res = (a[i] - res) + a[i];
162 return (res);
165 #endif /* _DOUBLE_IS_32BITS */