xref: /freebsd/lib/msun/src/e_asinf.c (revision 41e016289f77deb88b0ef1ec3f7b2ab3515ac7c8)
13a8617a8SJordan K. Hubbard /* e_asinf.c -- float version of e_asin.c.
23a8617a8SJordan K. Hubbard  * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
33a8617a8SJordan K. Hubbard  */
43a8617a8SJordan K. Hubbard 
53a8617a8SJordan K. Hubbard /*
63a8617a8SJordan K. Hubbard  * ====================================================
73a8617a8SJordan K. Hubbard  * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
83a8617a8SJordan K. Hubbard  *
93a8617a8SJordan K. Hubbard  * Developed at SunPro, a Sun Microsystems, Inc. business.
103a8617a8SJordan K. Hubbard  * Permission to use, copy, modify, and distribute this
113a8617a8SJordan K. Hubbard  * software is freely granted, provided that this notice
123a8617a8SJordan K. Hubbard  * is preserved.
133a8617a8SJordan K. Hubbard  * ====================================================
143a8617a8SJordan K. Hubbard  */
153a8617a8SJordan K. Hubbard 
163a8617a8SJordan K. Hubbard #include "math.h"
173a8617a8SJordan K. Hubbard #include "math_private.h"
183a8617a8SJordan K. Hubbard 
193a8617a8SJordan K. Hubbard static const float
203a8617a8SJordan K. Hubbard one =  1.0000000000e+00, /* 0x3F800000 */
21*41e01628SSteve Kargl huge =  1.000e+30;
22*41e01628SSteve Kargl 
23*41e01628SSteve Kargl /*
24*41e01628SSteve Kargl  * The coefficients for the rational approximation were generated over
25*41e01628SSteve Kargl  *  0x1p-12f <= x <= 0.5f.  The maximum error satisfies log2(e) < -30.084.
26*41e01628SSteve Kargl  */
27*41e01628SSteve Kargl static const float
28*41e01628SSteve Kargl pS0 =  1.66666672e-01f, /* 0x3e2aaaab */
29*41e01628SSteve Kargl pS1 = -1.19510300e-01f, /* 0xbdf4c1d1 */
30*41e01628SSteve Kargl pS2 =  5.47002675e-03f, /* 0x3bb33de9 */
31*41e01628SSteve Kargl qS1 = -1.16706085e+00f, /* 0xbf956240 */
32*41e01628SSteve Kargl qS2 =  2.90115148e-01f; /* 0x3e9489f9 */
338862f666SDavid Schultz 
348862f666SDavid Schultz static const double
358862f666SDavid Schultz pio2 =  1.570796326794896558e+00;
363a8617a8SJordan K. Hubbard 
37a82bbc73SAlfred Perlstein float
asinf(float x)3899843eb8SSteve Kargl asinf(float x)
393a8617a8SJordan K. Hubbard {
408862f666SDavid Schultz 	double s;
41941ab616SDavid Schultz 	float t,w,p,q;
423a8617a8SJordan K. Hubbard 	int32_t hx,ix;
433a8617a8SJordan K. Hubbard 	GET_FLOAT_WORD(hx,x);
443a8617a8SJordan K. Hubbard 	ix = hx&0x7fffffff;
45e0345583SDavid Schultz 	if(ix>=0x3f800000) {		/* |x| >= 1 */
46e0345583SDavid Schultz 	    if(ix==0x3f800000)		/* |x| == 1 */
47e0345583SDavid Schultz 		return x*pio2;		/* asin(+-1) = +-pi/2 with inexact */
483a8617a8SJordan K. Hubbard 	    return (x-x)/(x-x);		/* asin(|x|>1) is NaN */
493a8617a8SJordan K. Hubbard 	} else if (ix<0x3f000000) {	/* |x|<0.5 */
50e0345583SDavid Schultz 	    if(ix<0x39800000) {		/* |x| < 2**-12 */
513a8617a8SJordan K. Hubbard 		if(huge+x>one) return x;/* return x with inexact if x!=0*/
52e0345583SDavid Schultz 	    }
533a8617a8SJordan K. Hubbard 	    t = x*x;
548862f666SDavid Schultz 	    p = t*(pS0+t*(pS1+t*pS2));
55*41e01628SSteve Kargl 	    q = one+t*(qS1+t*qS2);
563a8617a8SJordan K. Hubbard 	    w = p/q;
573a8617a8SJordan K. Hubbard 	    return x+x*w;
583a8617a8SJordan K. Hubbard 	}
593a8617a8SJordan K. Hubbard 	/* 1> |x|>= 0.5 */
603a8617a8SJordan K. Hubbard 	w = one-fabsf(x);
613a8617a8SJordan K. Hubbard 	t = w*(float)0.5;
628862f666SDavid Schultz 	p = t*(pS0+t*(pS1+t*pS2));
63*41e01628SSteve Kargl 	q = one+t*(qS1+t*qS2);
64e0345583SDavid Schultz 	s = sqrt(t);
653a8617a8SJordan K. Hubbard 	w = p/q;
668862f666SDavid Schultz 	t = pio2-2.0*(s+s*w);
673a8617a8SJordan K. Hubbard 	if(hx>0) return t; else return -t;
683a8617a8SJordan K. Hubbard }
69