c1c42c7bc293022a71113e7fe9defa89b0f5b1cb
[musl] / src / math / asinf.c
1 /* origin: FreeBSD /usr/src/lib/msun/src/e_asinf.c */
2 /*
3  * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
4  */
5 /*
6  * ====================================================
7  * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
8  *
9  * Developed at SunPro, a Sun Microsystems, Inc. business.
10  * Permission to use, copy, modify, and distribute this
11  * software is freely granted, provided that this notice
12  * is preserved.
13  * ====================================================
14  */
15
16 #include "libm.h"
17
18 static const float
19 huge = 1.000e+30,
20 /* coefficients for R(x^2) */
21 pS0 =  1.6666586697e-01,
22 pS1 = -4.2743422091e-02,
23 pS2 = -8.6563630030e-03,
24 qS1 = -7.0662963390e-01;
25
26 static const double
27 pio2 = 1.570796326794896558e+00;
28
29 float asinf(float x)
30 {
31         double s;
32         float t,w,p,q;
33         int32_t hx,ix;
34
35         GET_FLOAT_WORD(hx, x);
36         ix = hx & 0x7fffffff;
37         if (ix >= 0x3f800000) {  /* |x| >= 1 */
38                 if (ix == 0x3f800000)  /* |x| == 1 */
39                         return x*pio2;  /* asin(+-1) = +-pi/2 with inexact */
40                 return (x-x)/(x-x);  /* asin(|x|>1) is NaN */
41         } else if (ix < 0x3f000000) {  /* |x|<0.5 */
42                 if (ix < 0x39800000) {  /* |x| < 2**-12 */
43                         if (huge+x > 1.0f)
44                                 return x; /* return x with inexact if x!=0 */
45                 }
46                 t = x*x;
47                 p = t*(pS0+t*(pS1+t*pS2));
48                 q = 1.0f+t*qS1;
49                 w = p/q;
50                 return x + x*w;
51         }
52         /* 1 > |x| >= 0.5 */
53         w = 1.0f - fabsf(x);
54         t = w*0.5f;
55         p = t*(pS0+t*(pS1+t*pS2));
56         q = 1.0f+t*qS1;
57         s = sqrt(t);
58         w = p/q;
59         t = pio2-2.0*(s+s*w);
60         if (hx > 0)
61                 return t;
62         return -t;
63 }