initial commit
[libm] / 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 one =  1.0000000000e+00, /* 0x3F800000 */
20 huge = 1.000e+30,
21 /* coefficients for R(x^2) */
22 pS0 =  1.6666586697e-01,
23 pS1 = -4.2743422091e-02,
24 pS2 = -8.6563630030e-03,
25 qS1 = -7.0662963390e-01;
26
27 static const double
28 pio2 = 1.570796326794896558e+00;
29
30 float asinf(float x)
31 {
32         double s;
33         float t,w,p,q;
34         int32_t hx,ix;
35
36         GET_FLOAT_WORD(hx, x);
37         ix = hx & 0x7fffffff;
38         if (ix >= 0x3f800000) {  /* |x| >= 1 */
39                 if (ix == 0x3f800000)  /* |x| == 1 */
40                         return x*pio2;  /* asin(+-1) = +-pi/2 with inexact */
41                 return (x-x)/(x-x);  /* asin(|x|>1) is NaN */
42         } else if (ix < 0x3f000000) {  /* |x|<0.5 */
43                 if (ix < 0x39800000) {  /* |x| < 2**-12 */
44                         if (huge+x > one)
45                                 return x; /* return x with inexact if x!=0 */
46                 }
47                 t = x*x;
48                 p = t*(pS0+t*(pS1+t*pS2));
49                 q = one+t*qS1;
50                 w = p/q;
51                 return x + x*w;
52         }
53         /* 1 > |x| >= 0.5 */
54         w = one - fabsf(x);
55         t = w*(float)0.5;
56         p = t*(pS0+t*(pS1+t*pS2));
57         q = one+t*qS1;
58         s = sqrt(t);
59         w = p/q;
60         t = pio2-2.0*(s+s*w);
61         if (hx > 0)
62                 return t;
63         return -t;
64 }