POK
e_acosf.c
1 /*
2  * POK header
3  *
4  * The following file is a part of the POK project. Any modification should
5  * made according to the POK licence. You CANNOT use this file or a part of
6  * this file is this part of a file for your own project
7  *
8  * For more information on the POK licence, please see our LICENCE FILE
9  *
10  * Please follow the coding guidelines described in doc/CODING_GUIDELINES
11  *
12  * Copyright (c) 2007-2009 POK team
13  *
14  * Created by julien on Fri Jan 30 14:41:34 2009
15  */
16 
17 /* e_acosf.c -- float version of e_acos.c.
18  * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
19  */
20 
21 /*
22  * ====================================================
23  * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
24  *
25  * Developed at SunPro, a Sun Microsystems, Inc. business.
26  * Permission to use, copy, modify, and distribute this
27  * software is freely granted, provided that this notice
28  * is preserved.
29  * ====================================================
30  */
31 
32 #ifdef POK_NEEDS_LIBMATH
33 
34 #include "math_private.h"
35 
36 static const float
37 one = 1.0000000000e+00, /* 0x3F800000 */
38 pi = 3.1415925026e+00, /* 0x40490fda */
39 pio2_hi = 1.5707962513e+00, /* 0x3fc90fda */
40 pio2_lo = 7.5497894159e-08, /* 0x33a22168 */
41 pS0 = 1.6666667163e-01, /* 0x3e2aaaab */
42 pS1 = -3.2556581497e-01, /* 0xbea6b090 */
43 pS2 = 2.0121252537e-01, /* 0x3e4e0aa8 */
44 pS3 = -4.0055535734e-02, /* 0xbd241146 */
45 pS4 = 7.9153501429e-04, /* 0x3a4f7f04 */
46 pS5 = 3.4793309169e-05, /* 0x3811ef08 */
47 qS1 = -2.4033949375e+00, /* 0xc019d139 */
48 qS2 = 2.0209457874e+00, /* 0x4001572d */
49 qS3 = -6.8828397989e-01, /* 0xbf303361 */
50 qS4 = 7.7038154006e-02; /* 0x3d9dc62e */
51 
52 float
53 __ieee754_acosf(float x)
54 {
55  float z,p,q,r,w,s,c,df;
56  int32_t hx,ix;
57  GET_FLOAT_WORD(hx,x);
58  ix = hx&0x7fffffff;
59  if(ix==0x3f800000) { /* |x|==1 */
60  if(hx>0) return 0.0; /* acos(1) = 0 */
61  else return pi+(float)2.0*pio2_lo; /* acos(-1)= pi */
62  } else if(ix>0x3f800000) { /* |x| >= 1 */
63  return (x-x)/(x-x); /* acos(|x|>1) is NaN */
64  }
65  if(ix<0x3f000000) { /* |x| < 0.5 */
66  if(ix<=0x23000000) return pio2_hi+pio2_lo;/*if|x|<2**-57*/
67  z = x*x;
68  p = z*(pS0+z*(pS1+z*(pS2+z*(pS3+z*(pS4+z*pS5)))));
69  q = one+z*(qS1+z*(qS2+z*(qS3+z*qS4)));
70  r = p/q;
71  return pio2_hi - (x - (pio2_lo-x*r));
72  } else if (hx<0) { /* x < -0.5 */
73  z = (one+x)*(float)0.5;
74  p = z*(pS0+z*(pS1+z*(pS2+z*(pS3+z*(pS4+z*pS5)))));
75  q = one+z*(qS1+z*(qS2+z*(qS3+z*qS4)));
76  s = __ieee754_sqrtf(z);
77  r = p/q;
78  w = r*s-pio2_lo;
79  return pi - (float)2.0*(s+w);
80  } else { /* x > 0.5 */
81  int32_t idf;
82  z = (one-x)*(float)0.5;
83  s = __ieee754_sqrtf(z);
84  df = s;
85  GET_FLOAT_WORD(idf,df);
86  SET_FLOAT_WORD(df,idf&0xfffff000);
87  c = (z-df*df)/(s+df);
88  p = z*(pS0+z*(pS1+z*(pS2+z*(pS3+z*(pS4+z*pS5)))));
89  q = one+z*(qS1+z*(qS2+z*(qS3+z*qS4)));
90  r = p/q;
91  w = r*s+c;
92  return (float)2.0*(df+w);
93  }
94 }
95 #endif
96