Blame sysdeps/ieee754/flt-32/e_asinf.c

Packit 6c4009
/* e_asinf.c -- float version of e_asin.c.
Packit 6c4009
 * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
Packit 6c4009
 */
Packit 6c4009
Packit 6c4009
/*
Packit 6c4009
 * ====================================================
Packit 6c4009
 * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
Packit 6c4009
 *
Packit 6c4009
 * Developed at SunPro, a Sun Microsystems, Inc. business.
Packit 6c4009
 * Permission to use, copy, modify, and distribute this
Packit 6c4009
 * software is freely granted, provided that this notice
Packit 6c4009
 * is preserved.
Packit 6c4009
 * ====================================================
Packit 6c4009
 */
Packit 6c4009
Packit 6c4009
/*
Packit 6c4009
  Modifications for single precision expansion are
Packit 6c4009
  Copyright (C) 2001 Stephen L. Moshier <moshier@na-net.ornl.gov>
Packit 6c4009
  and are incorporated herein by permission of the author.  The author
Packit 6c4009
  reserves the right to distribute this material elsewhere under different
Packit 6c4009
  copying permissions.  These modifications are distributed here under
Packit 6c4009
  the following terms:
Packit 6c4009
Packit 6c4009
    This library is free software; you can redistribute it and/or
Packit 6c4009
    modify it under the terms of the GNU Lesser General Public
Packit 6c4009
    License as published by the Free Software Foundation; either
Packit 6c4009
    version 2.1 of the License, or (at your option) any later version.
Packit 6c4009
Packit 6c4009
    This library is distributed in the hope that it will be useful,
Packit 6c4009
    but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit 6c4009
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit 6c4009
    Lesser General Public License for more details.
Packit 6c4009
Packit 6c4009
    You should have received a copy of the GNU Lesser General Public
Packit 6c4009
    License along with this library; if not, see
Packit 6c4009
    <http://www.gnu.org/licenses/>.  */
Packit 6c4009
Packit 6c4009
#if defined(LIBM_SCCS) && !defined(lint)
Packit 6c4009
static char rcsid[] = "$NetBSD: e_asinf.c,v 1.5 1995/05/12 04:57:25 jtc Exp $";
Packit 6c4009
#endif
Packit 6c4009
Packit 6c4009
#include <float.h>
Packit 6c4009
#include <math.h>
Packit 6c4009
#include <math_private.h>
Packit 6c4009
#include <math-underflow.h>
Packit 6c4009
Packit 6c4009
static const float
Packit 6c4009
one =  1.0000000000e+00, /* 0x3F800000 */
Packit 6c4009
huge =  1.000e+30,
Packit 6c4009
Packit 6c4009
pio2_hi = 1.57079637050628662109375f,
Packit 6c4009
pio2_lo = -4.37113900018624283e-8f,
Packit 6c4009
pio4_hi = 0.785398185253143310546875f,
Packit 6c4009
Packit 6c4009
/* asin x = x + x^3 p(x^2)
Packit 6c4009
   -0.5 <= x <= 0.5;
Packit 6c4009
   Peak relative error 4.8e-9 */
Packit 6c4009
p0 = 1.666675248e-1f,
Packit 6c4009
p1 = 7.495297643e-2f,
Packit 6c4009
p2 = 4.547037598e-2f,
Packit 6c4009
p3 = 2.417951451e-2f,
Packit 6c4009
p4 = 4.216630880e-2f;
Packit 6c4009
Packit 6c4009
float __ieee754_asinf(float x)
Packit 6c4009
{
Packit 6c4009
	float t,w,p,q,c,r,s;
Packit 6c4009
	int32_t hx,ix;
Packit 6c4009
	GET_FLOAT_WORD(hx,x);
Packit 6c4009
	ix = hx&0x7fffffff;
Packit 6c4009
	if(ix==0x3f800000) {
Packit 6c4009
		/* asin(1)=+-pi/2 with inexact */
Packit 6c4009
	    return x*pio2_hi+x*pio2_lo;
Packit 6c4009
	} else if(ix> 0x3f800000) {	/* |x|>= 1 */
Packit 6c4009
	    return (x-x)/(x-x);		/* asin(|x|>1) is NaN */
Packit 6c4009
	} else if (ix<0x3f000000) {	/* |x|<0.5 */
Packit 6c4009
	    if(ix<0x32000000) {		/* if |x| < 2**-27 */
Packit 6c4009
		math_check_force_underflow (x);
Packit 6c4009
		if(huge+x>one) return x;/* return x with inexact if x!=0*/
Packit 6c4009
	    } else {
Packit 6c4009
		t = x*x;
Packit 6c4009
		w = t * (p0 + t * (p1 + t * (p2 + t * (p3 + t * p4))));
Packit 6c4009
		return x+x*w;
Packit 6c4009
	    }
Packit 6c4009
	}
Packit 6c4009
	/* 1> |x|>= 0.5 */
Packit 6c4009
	w = one-fabsf(x);
Packit 6c4009
	t = w*0.5f;
Packit 6c4009
	p = t * (p0 + t * (p1 + t * (p2 + t * (p3 + t * p4))));
Packit 6c4009
	s = sqrtf(t);
Packit 6c4009
	if(ix>=0x3F79999A) {	/* if |x| > 0.975 */
Packit 6c4009
	    t = pio2_hi-(2.0f*(s+s*p)-pio2_lo);
Packit 6c4009
	} else {
Packit 6c4009
	    int32_t iw;
Packit 6c4009
	    w  = s;
Packit 6c4009
	    GET_FLOAT_WORD(iw,w);
Packit 6c4009
	    SET_FLOAT_WORD(w,iw&0xfffff000);
Packit 6c4009
	    c  = (t-w*w)/(s+w);
Packit 6c4009
	    r  = p;
Packit 6c4009
	    p  = 2.0f*s*r-(pio2_lo-2.0f*c);
Packit 6c4009
	    q  = pio4_hi-2.0f*w;
Packit 6c4009
	    t  = pio4_hi-(p-q);
Packit 6c4009
	}
Packit 6c4009
	if(hx>0) return t; else return -t;
Packit 6c4009
}
Packit 6c4009
strong_alias (__ieee754_asinf, __asinf_finite)