예제 #1
0
float
__asinhf(float x)
{
	float w;
	int32_t hx,ix;
	GET_FLOAT_WORD(hx,x);
	ix = hx&0x7fffffff;
	if(__builtin_expect(ix< 0x38000000, 0)) {	/* |x|<2**-14 */
	    math_check_force_underflow (x);
	    if(huge+x>one) return x;	/* return x inexact except 0 */
	}
	if(__builtin_expect(ix>0x47000000, 0)) {	/* |x| > 2**14 */
	    if(ix>=0x7f800000) return x+x;	/* x is inf or NaN */
	    w = __ieee754_logf(fabsf(x))+ln2;
	} else {
	    float xa = fabsf(x);
	    if (ix>0x40000000) {	/* 2**14 > |x| > 2.0 */
		w = __ieee754_logf(2.0f*xa+one/(__ieee754_sqrtf(xa*xa+one)+xa));
	    } else {		/* 2.0 > |x| > 2**-14 */
		float t = xa*xa;
		w =__log1pf(xa+t/(one+__ieee754_sqrtf(one+t)));
	    }
	}
	return __copysignf(w, x);
}
예제 #2
0
float
__ieee754_y1f(float x)
{
	float z, s,c,ss,cc,u,v;
	int32_t hx,ix;

	GET_FLOAT_WORD(hx,x);
	ix = 0x7fffffff&hx;
    /* if Y1(NaN) is NaN, Y1(-inf) is NaN, Y1(inf) is 0 */
	if(__builtin_expect(ix>=0x7f800000, 0)) return  one/(x+x*x);
	if(__builtin_expect(ix==0, 0))
		return -HUGE_VALF+x;  /* -inf and overflow exception.  */
	if(__builtin_expect(hx<0, 0)) return zero/(zero*x);
	if(ix >= 0x40000000) {  /* |x| >= 2.0 */
		SET_RESTORE_ROUNDF (FE_TONEAREST);
		__sincosf (x, &s, &c);
		ss = -s-c;
		cc = s-c;
		if(ix<0x7f000000) {  /* make sure x+x not overflow */
		    z = __cosf(x+x);
		    if ((s*c)>zero) cc = z/ss;
		    else            ss = z/cc;
		}
	/* y1(x) = sqrt(2/(pi*x))*(p1(x)*sin(x0)+q1(x)*cos(x0))
	 * where x0 = x-3pi/4
	 *      Better formula:
	 *              cos(x0) = cos(x)cos(3pi/4)+sin(x)sin(3pi/4)
	 *                      =  1/sqrt(2) * (sin(x) - cos(x))
	 *              sin(x0) = sin(x)cos(3pi/4)-cos(x)sin(3pi/4)
	 *                      = -1/sqrt(2) * (cos(x) + sin(x))
	 * To avoid cancellation, use
	 *              sin(x) +- cos(x) = -cos(2x)/(sin(x) -+ cos(x))
	 * to compute the worse one.
	 */
		if(ix>0x48000000) z = (invsqrtpi*ss)/__ieee754_sqrtf(x);
		else {
		    u = ponef(x); v = qonef(x);
		    z = invsqrtpi*(u*ss+v*cc)/__ieee754_sqrtf(x);
		}
		return z;
	}
	if(__builtin_expect(ix<=0x33000000, 0)) {    /* x < 2**-25 */
	    z = -tpi / x;
	    if (__isinff (z))
		__set_errno (ERANGE);
	    return z;
	}
	z = x*x;
	u = U0[0]+z*(U0[1]+z*(U0[2]+z*(U0[3]+z*U0[4])));
	v = one+z*(V0[0]+z*(V0[1]+z*(V0[2]+z*(V0[3]+z*V0[4]))));
	return(x*(u/v) + tpi*(__ieee754_j1f(x)*__ieee754_logf(x)-one/x));
}
예제 #3
0
float
__ieee754_y0f(float x)
{
	float z, s,c,ss,cc,u,v;
	int32_t hx,ix;

	GET_FLOAT_WORD(hx,x);
	ix = 0x7fffffff&hx;
    /* Y0(NaN) is NaN, y0(-inf) is Nan, y0(inf) is 0, y0(0) is -inf.  */
	if(ix>=0x7f800000) return  one/(x+x*x);
	if(ix==0) return -HUGE_VALF+x;  /* -inf and overflow exception.  */
	if(hx<0) return zero/(zero*x);
	if(ix >= 0x40000000) {  /* |x| >= 2.0 */
	/* y0(x) = sqrt(2/(pi*x))*(p0(x)*sin(x0)+q0(x)*cos(x0))
	 * where x0 = x-pi/4
	 *      Better formula:
	 *              cos(x0) = cos(x)cos(pi/4)+sin(x)sin(pi/4)
	 *                      =  1/sqrt(2) * (sin(x) + cos(x))
	 *              sin(x0) = sin(x)cos(3pi/4)-cos(x)sin(3pi/4)
	 *                      =  1/sqrt(2) * (sin(x) - cos(x))
	 * To avoid cancellation, use
	 *              sin(x) +- cos(x) = -cos(2x)/(sin(x) -+ cos(x))
	 * to compute the worse one.
	 */
		__sincosf (x, &s, &c);
		ss = s-c;
		cc = s+c;
	/*
	 * j0(x) = 1/sqrt(pi) * (P(0,x)*cc - Q(0,x)*ss) / sqrt(x)
	 * y0(x) = 1/sqrt(pi) * (P(0,x)*ss + Q(0,x)*cc) / sqrt(x)
	 */
		if(ix<0x7f000000) {  /* make sure x+x not overflow */
		    z = -__cosf(x+x);
		    if ((s*c)<zero) cc = z/ss;
		    else            ss = z/cc;
		}
		if(ix>0x48000000) z = (invsqrtpi*ss)/__ieee754_sqrtf(x);
		else {
		    u = pzerof(x); v = qzerof(x);
		    z = invsqrtpi*(u*ss+v*cc)/__ieee754_sqrtf(x);
		}
		return z;
	}
	if(ix<=0x32000000) {	/* x < 2**-27 */
	    return(u00 + tpi*__ieee754_logf(x));
	}
	z = x*x;
	u = u00+z*(u01+z*(u02+z*(u03+z*(u04+z*(u05+z*u06)))));
	v = one+z*(v01+z*(v02+z*(v03+z*v04)));
	return(u/v + tpi*(__ieee754_j0f(x)*__ieee754_logf(x)));
}
예제 #4
0
float
sqrtf(float x)		/* wrapper sqrtf */
{
#ifdef _IEEE_LIBM
	return __ieee754_sqrtf(x);
#else
	float z;
	z = __ieee754_sqrtf(x);
	if(_LIB_VERSION == _IEEE_ || isnanf(x)) return z;
	if(x<(float)0.0) {
	    /* sqrtf(negative) */
	    return (float)__kernel_standard((double)x,(double)x,126);
	} else
	    return z;
#endif
}
예제 #5
0
파일: w_sqrtf.c 프로젝트: AubrCool/glibc
/* wrapper sqrtf */
float
__sqrtf (float x)
{
  if (__builtin_expect (isless (x, 0.0f), 0) && _LIB_VERSION != _IEEE_)
    return __kernel_standard_f (x, x, 126); /* sqrt(negative) */

  return __ieee754_sqrtf (x);
}
예제 #6
0
float
__ieee754_j0f(float x)
{
	float z, s,c,ss,cc,r,u,v;
	int32_t hx,ix;

	GET_FLOAT_WORD(hx,x);
	ix = hx&0x7fffffff;
	if(ix>=0x7f800000) return one/(x*x);
	x = fabsf(x);
	if(ix >= 0x40000000) {	/* |x| >= 2.0 */
		__sincosf (x, &s, &c);
		ss = s-c;
		cc = s+c;
		if(ix<0x7f000000) {  /* make sure x+x not overflow */
		    z = -__cosf(x+x);
		    if ((s*c)<zero) cc = z/ss;
		    else	    ss = z/cc;
		}
	/*
	 * j0(x) = 1/sqrt(pi) * (P(0,x)*cc - Q(0,x)*ss) / sqrt(x)
	 * y0(x) = 1/sqrt(pi) * (P(0,x)*ss + Q(0,x)*cc) / sqrt(x)
	 */
		if(ix>0x48000000) z = (invsqrtpi*cc)/__ieee754_sqrtf(x);
		else {
		    u = pzerof(x); v = qzerof(x);
		    z = invsqrtpi*(u*cc-v*ss)/__ieee754_sqrtf(x);
		}
		return z;
	}
	if(ix<0x39000000) {	/* |x| < 2**-13 */
	    math_force_eval(huge+x);		/* raise inexact if x != 0 */
	    if(ix<0x32000000) return one;	/* |x|<2**-27 */
	    else	      return one - (float)0.25*x*x;
	}
	z = x*x;
	r =  z*(R02+z*(R03+z*(R04+z*R05)));
	s =  one+z*(S01+z*(S02+z*(S03+z*S04)));
	if(ix < 0x3F800000) {	/* |x| < 1.00 */
	    return one + z*((float)-0.25+(r/s));
	} else {
	    u = (float)0.5*x;
	    return((one+u)*(one-u)+z*(r/s));
	}
}
예제 #7
0
파일: acosh.cpp 프로젝트: chenbk85/QOR
    //------------------------------------------------------------------------------
    float Cmath::__ieee754_acoshf( float x )
    {
        static const float one	= 1.0;
        static const float ln2	= 6.9314718246e-01;  // 0x3f317218

        float t;
        Cmp_signed__int32 hx;
        get_float_word( hx, x );
        if( hx < 0x3f800000 )
        {
            // x < 1
            return ( x - x ) / ( x - x );
        }
        else if( hx >= 0x4d800000 )
        {
            // x > 2**28
            if( !uword_isfinite( hx ) )
            {
                // x is inf of NaN
                return x + x;
            }
            else
            {
                return __ieee754_logf( x ) + ln2; // acosh(huge)=log(2x)
            }
        }
        else if ( hx == 0x3f800000 )
        {
            return 0.0; // acosh(1) = 0
        }
        else if ( hx > 0x40000000 )
        {
            // 2**28 > x > 2
            t = x * x;
            return __ieee754_logf( (float)2.0 * x - one / ( x + __ieee754_sqrtf( t - one ) ) );
        }
        else
        {
            // 1<x<2
            t = x - one;
            return log1pf( t + __ieee754_sqrtf( (float)2.0 * t + t * t ) );
        }
    }
예제 #8
0
파일: e_acosf.c 프로젝트: efidroid/edk2
float
__ieee754_acosf(float x)
{
	float z,p,q,r,w,s,c,df;
	int32_t hx,ix;
	GET_FLOAT_WORD(hx,x);
	ix = hx&0x7fffffff;
	if(ix==0x3f800000) {		/* |x|==1 */
	    if(hx>0) return 0.0;	/* acos(1) = 0  */
	    else return pi+(float)2.0*pio2_lo;	/* acos(-1)= pi */
	} else if(ix>0x3f800000) {	/* |x| >= 1 */
	    return (x-x)/(x-x);		/* acos(|x|>1) is NaN */
	}
	if(ix<0x3f000000) {	/* |x| < 0.5 */
	    if(ix<=0x23000000) return pio2_hi+pio2_lo;/*if|x|<2**-57*/
	    z = x*x;
	    p = z*(pS0+z*(pS1+z*(pS2+z*(pS3+z*(pS4+z*pS5)))));
	    q = one+z*(qS1+z*(qS2+z*(qS3+z*qS4)));
	    r = p/q;
	    return pio2_hi - (x - (pio2_lo-x*r));
	} else  if (hx<0) {		/* x < -0.5 */
	    z = (one+x)*(float)0.5;
	    p = z*(pS0+z*(pS1+z*(pS2+z*(pS3+z*(pS4+z*pS5)))));
	    q = one+z*(qS1+z*(qS2+z*(qS3+z*qS4)));
	    s = __ieee754_sqrtf(z);
	    r = p/q;
	    w = r*s-pio2_lo;
	    return pi - (float)2.0*(s+w);
	} else {			/* x > 0.5 */
	    int32_t idf;
	    z = (one-x)*(float)0.5;
	    s = __ieee754_sqrtf(z);
	    df = s;
	    GET_FLOAT_WORD(idf,df);
	    SET_FLOAT_WORD(df,idf&0xfffff000);
	    c  = (z-df*df)/(s+df);
	    p = z*(pS0+z*(pS1+z*(pS2+z*(pS3+z*(pS4+z*pS5)))));
	    q = one+z*(qS1+z*(qS2+z*(qS3+z*qS4)));
	    r = p/q;
	    w = r*s+c;
	    return (float)2.0*(df+w);
	}
}
예제 #9
0
float
__ieee754_j1f(float x)
{
	float z, s,c,ss,cc,r,u,v,y;
	int32_t hx,ix;

	GET_FLOAT_WORD(hx,x);
	ix = hx&0x7fffffff;
	if(__builtin_expect(ix>=0x7f800000, 0)) return one/x;
	y = fabsf(x);
	if(ix >= 0x40000000) {	/* |x| >= 2.0 */
		__sincosf (y, &s, &c);
		ss = -s-c;
		cc = s-c;
		if(ix<0x7f000000) {  /* make sure y+y not overflow */
		    z = __cosf(y+y);
		    if ((s*c)>zero) cc = z/ss;
		    else	    ss = z/cc;
		}
	/*
	 * j1(x) = 1/sqrt(pi) * (P(1,x)*cc - Q(1,x)*ss) / sqrt(x)
	 * y1(x) = 1/sqrt(pi) * (P(1,x)*ss + Q(1,x)*cc) / sqrt(x)
	 */
		if(ix>0x48000000) z = (invsqrtpi*cc)/__ieee754_sqrtf(y);
		else {
		    u = ponef(y); v = qonef(y);
		    z = invsqrtpi*(u*cc-v*ss)/__ieee754_sqrtf(y);
		}
		if(hx<0) return -z;
		else	 return  z;
	}
	if(__builtin_expect(ix<0x32000000, 0)) {	/* |x|<2**-27 */
	    if(huge+x>one) return (float)0.5*x;/* inexact if x!=0 necessary */
	}
	z = x*x;
	r =  z*(r00+z*(r01+z*(r02+z*r03)));
	s =  one+z*(s01+z*(s02+z*(s03+z*(s04+z*s05))));
	r *= x;
	return(x*(float)0.5+r/s);
}
예제 #10
0
파일: s_asinhf.c 프로젝트: JinSeok/GIT_Test
float
asinhf(float x)
{
	float t,w;
	int32_t hx,ix;
	GET_FLOAT_WORD(hx,x);
	ix = hx&0x7fffffff;
	if(ix>=0x7f800000) return x+x;	/* x is inf or NaN */
	if(ix< 0x31800000) {	/* |x|<2**-28 */
	    if(huge+x>one) return x;	/* return x inexact except 0 */
	}
	if(ix>0x4d800000) {	/* |x| > 2**28 */
	    w = __ieee754_logf(fabsf(x))+ln2;
	} else if (ix>0x40000000) {	/* 2**28 > |x| > 2.0 */
	    t = fabsf(x);
	    w = __ieee754_logf((float)2.0*t+one/(__ieee754_sqrtf(x*x+one)+t));
	} else {		/* 2.0 > |x| > 2**-28 */
	    t = x*x;
	    w =log1pf(fabsf(x)+t/(one+__ieee754_sqrtf(one+t)));
	}
	if(hx>0) return w; else return -w;
}
예제 #11
0
float
__ieee754_acoshf(float x)
{
	float t;
	int32_t hx;
	GET_FLOAT_WORD(hx,x);
	if(hx<0x3f800000) {		/* x < 1 */
	    return (x-x)/(x-x);
	} else if(hx >=0x4d800000) {	/* x > 2**28 */
	    if(hx >=0x7f800000) {	/* x is inf of NaN */
	        return x+x;
	    } else
		return __ieee754_logf(x)+ln2;	/* acosh(huge)=log(2x) */
	} else if (hx==0x3f800000) {
	    return 0.0;			/* acosh(1) = 0 */
	} else if (hx > 0x40000000) {	/* 2**28 > x > 2 */
	    t=x*x;
	    return __ieee754_logf((float)2.0*x-one/(x+__ieee754_sqrtf(t-one)));
	} else {			/* 1<x<2 */
	    t = x-one;
	    return log1pf(t+__ieee754_sqrtf((float)2.0*t+t*t));
	}
}
예제 #12
0
파일: e_asinf.c 프로젝트: HuaiYuSched/pok
float
__ieee754_asinf(float x)
{
	float t,w,p,q,c,r,s;
	int32_t hx,ix;

	t = 0;
	GET_FLOAT_WORD(hx,x);
	ix = hx&0x7fffffff;
	if(ix==0x3f800000) {
		/* asin(1)=+-pi/2 with inexact */
	    return x*pio2_hi+x*pio2_lo;
	} else if(ix> 0x3f800000) {	/* |x|>= 1 */
	    return (x-x)/(x-x);		/* asin(|x|>1) is NaN */
	} else if (ix<0x3f000000) {	/* |x|<0.5 */
	    if(ix<0x32000000) {		/* if |x| < 2**-27 */
		if(huge+x>one) return x;/* return x with inexact if x!=0*/
	    } else
		t = x*x;
		p = t*(pS0+t*(pS1+t*(pS2+t*(pS3+t*(pS4+t*pS5)))));
		q = one+t*(qS1+t*(qS2+t*(qS3+t*qS4)));
		w = p/q;
		return x+x*w;
	}
	/* 1> |x|>= 0.5 */
	w = one-fabsf(x);
	t = w*(float)0.5;
	p = t*(pS0+t*(pS1+t*(pS2+t*(pS3+t*(pS4+t*pS5)))));
	q = one+t*(qS1+t*(qS2+t*(qS3+t*qS4)));
	s = __ieee754_sqrtf(t);
	if(ix>=0x3F79999A) { 	/* if |x| > 0.975 */
	    w = p/q;
	    t = pio2_hi-((float)2.0*(s+s*w)-pio2_lo);
	} else {
	    int32_t iw;
	    w  = s;
	    GET_FLOAT_WORD(iw,w);
	    SET_FLOAT_WORD(w,iw&0xfffff000);
	    c  = (t-w*w)/(s+w);
	    r  = p/q;
	    p  = (float)2.0*s*r-(pio2_lo-(float)2.0*c);
	    q  = pio4_hi-(float)2.0*w;
	    t  = pio4_hi-(p-q);
	}
	if(hx>0) return t; else return -t;
}
예제 #13
0
float __ieee754_asinf(float x)
{
	float t,w,p,q,c,r,s;
	int32_t hx,ix;
	GET_FLOAT_WORD(hx,x);
	ix = hx&0x7fffffff;
	if(ix==0x3f800000) {
		/* asin(1)=+-pi/2 with inexact */
	    return x*pio2_hi+x*pio2_lo;
	} else if(ix> 0x3f800000) {	/* |x|>= 1 */
	    return (x-x)/(x-x);		/* asin(|x|>1) is NaN */
	} else if (ix<0x3f000000) {	/* |x|<0.5 */
	    if(ix<0x32000000) {		/* if |x| < 2**-27 */
		if(huge+x>one) return x;/* return x with inexact if x!=0*/
	    } else {
		t = x*x;
		w = t * (p0 + t * (p1 + t * (p2 + t * (p3 + t * p4))));
		return x+x*w;
	    }
	}
	/* 1> |x|>= 0.5 */
	w = one-fabsf(x);
	t = w*0.5f;
	p = t * (p0 + t * (p1 + t * (p2 + t * (p3 + t * p4))));
	s = __ieee754_sqrtf(t);
	if(ix>=0x3F79999A) {	/* if |x| > 0.975 */
	    t = pio2_hi-(2.0f*(s+s*p)-pio2_lo);
	} else {
	    int32_t iw;
	    w  = s;
	    GET_FLOAT_WORD(iw,w);
	    SET_FLOAT_WORD(w,iw&0xfffff000);
	    c  = (t-w*w)/(s+w);
	    r  = p;
	    p  = 2.0f*s*r-(pio2_lo-2.0f*c);
	    q  = pio4_hi-2.0f*w;
	    t  = pio4_hi-(p-q);
	}
	if(hx>0) return t; else return -t;
}
예제 #14
0
파일: s_csqrtf.c 프로젝트: Xilinx/eglibc
__complex__ float
__csqrtf (__complex__ float x)
{
  __complex__ float res;
  int rcls = fpclassify (__real__ x);
  int icls = fpclassify (__imag__ x);

  if (__builtin_expect (rcls <= FP_INFINITE || icls <= FP_INFINITE, 0))
    {
      if (icls == FP_INFINITE)
	{
	  __real__ res = HUGE_VALF;
	  __imag__ res = __imag__ x;
	}
      else if (rcls == FP_INFINITE)
	{
	  if (__real__ x < 0.0)
	    {
	      __real__ res = icls == FP_NAN ? __nanf ("") : 0;
	      __imag__ res = __copysignf (HUGE_VALF, __imag__ x);
	    }
	  else
	    {
	      __real__ res = __real__ x;
	      __imag__ res = (icls == FP_NAN
			      ? __nanf ("") : __copysignf (0.0, __imag__ x));
	    }
	}
      else
	{
	  __real__ res = __nanf ("");
	  __imag__ res = __nanf ("");
	}
    }
  else
    {
      if (__builtin_expect (icls == FP_ZERO, 0))
	{
	  if (__real__ x < 0.0)
	    {
	      __real__ res = 0.0;
	      __imag__ res = __copysignf (__ieee754_sqrtf (-__real__ x),
					  __imag__ x);
	    }
	  else
	    {
	      __real__ res = fabsf (__ieee754_sqrtf (__real__ x));
	      __imag__ res = __copysignf (0.0, __imag__ x);
	    }
	}
      else if (__builtin_expect (rcls == FP_ZERO, 0))
	{
	  float r;
	  if (fabsf (__imag__ x) >= 2.0f * FLT_MIN)
	    r = __ieee754_sqrtf (0.5f * fabsf (__imag__ x));
	  else
	    r = 0.5f * __ieee754_sqrtf (2.0f * fabsf (__imag__ x));

	  __real__ res = r;
	  __imag__ res = __copysignf (r, __imag__ x);
	}
      else
	{
	  float d, r, s;
	  int scale = 0;

	  if (fabsf (__real__ x) > FLT_MAX / 4.0f)
	    {
	      scale = 1;
	      __real__ x = __scalbnf (__real__ x, -2 * scale);
	      __imag__ x = __scalbnf (__imag__ x, -2 * scale);
	    }
	  else if (fabsf (__imag__ x) > FLT_MAX / 4.0f)
	    {
	      scale = 1;
	      if (fabsf (__real__ x) >= 4.0f * FLT_MIN)
		__real__ x = __scalbnf (__real__ x, -2 * scale);
	      else
		__real__ x = 0.0f;
	      __imag__ x = __scalbnf (__imag__ x, -2 * scale);
	    }
	  else if (fabsf (__real__ x) < FLT_MIN
		   && fabsf (__imag__ x) < FLT_MIN)
	    {
	      scale = -(FLT_MANT_DIG / 2);
	      __real__ x = __scalbnf (__real__ x, -2 * scale);
	      __imag__ x = __scalbnf (__imag__ x, -2 * scale);
	    }

	  d = __ieee754_hypotf (__real__ x, __imag__ x);
	  /* Use the identity   2  Re res  Im res = Im x
	     to avoid cancellation error in  d +/- Re x.  */
	  if (__real__ x > 0)
	    {
	      r = __ieee754_sqrtf (0.5f * (d + __real__ x));
	      s = 0.5f * (__imag__ x / r);
	    }
	  else
	    {
	      s = __ieee754_sqrtf (0.5f * (d - __real__ x));
	      r = fabsf (0.5f * (__imag__ x / s));
	    }

	  if (scale)
	    {
	      r = __scalbnf (r, scale);
	      s = __scalbnf (s, scale);
	    }

	  __real__ res = r;
	  __imag__ res = __copysignf (s, __imag__ x);
	}
    }

  return res;
}
예제 #15
0
__complex__ float
__cacoshf (__complex__ float x)
{
  __complex__ float res;
  int rcls = fpclassify (__real__ x);
  int icls = fpclassify (__imag__ x);

  if (rcls <= FP_INFINITE || icls <= FP_INFINITE)
    {
      if (icls == FP_INFINITE)
	{
	  __real__ res = HUGE_VALF;

	  if (rcls == FP_NAN)
	    __imag__ res = __nanf ("");
	  else
	    __imag__ res = __copysignf ((rcls == FP_INFINITE
					 ? (__real__ x < 0.0
					    ? M_PI - M_PI_4 : M_PI_4)
					 : M_PI_2), __imag__ x);
	}
      else if (rcls == FP_INFINITE)
	{
	  __real__ res = HUGE_VALF;

	  if (icls >= FP_ZERO)
	    __imag__ res = __copysignf (signbit (__real__ x) ? M_PI : 0.0,
					__imag__ x);
	  else
	    __imag__ res = __nanf ("");
	}
      else
	{
	  __real__ res = __nanf ("");
	  __imag__ res = __nanf ("");
	}
    }
  else if (rcls == FP_ZERO && icls == FP_ZERO)
    {
      __real__ res = 0.0;
      __imag__ res = __copysignf (M_PI_2, __imag__ x);
    }
  else
    {
#if 1
      __complex__ float y;

      __real__ y = (__real__ x - __imag__ x) * (__real__ x + __imag__ x) - 1.0;
      __imag__ y = 2.0 * __real__ x * __imag__ x;

      y = __csqrtf (y);

      if (__real__ x < 0.0)
	y = -y;

      __real__ y += __real__ x;
      __imag__ y += __imag__ x;

      res = __clogf (y);
#else
      float re2 = __real__ x * __real__ x;
      float im2 = __imag__ x * __imag__ x;
      float sq = re2 - im2 - 1.0;
      float ro = __ieee754_sqrtf (sq * sq + 4 * re2 * im2);
      float a = __ieee754_sqrtf ((sq + ro) / 2.0);
      float b = __ieee754_sqrtf ((-sq + ro) / 2.0);

      __real__ res = 0.5 * __ieee754_logf (re2 + __real__ x * 2 * a
					   + im2 + __imag__ x * 2 * b
					   + ro);
      __imag__ res = __ieee754_atan2f (__imag__ x + b, __real__ x + a);
#endif

      /* We have to use the positive branch.  */
      if (__real__ res < 0.0)
	res = -res;
    }

  return res;
}
예제 #16
0
__complex__ float
__csqrtf (__complex__ float x)
{
  __complex__ float res;
  int rcls = fpclassify (__real__ x);
  int icls = fpclassify (__imag__ x);

  if (rcls <= FP_INFINITE || icls <= FP_INFINITE)
    {
      if (icls == FP_INFINITE)
	{
	  __real__ res = HUGE_VALF;
	  __imag__ res = __imag__ x;
	}
      else if (rcls == FP_INFINITE)
	{
	  if (__real__ x < 0.0)
	    {
	      __real__ res = icls == FP_NAN ? __nanf ("") : 0;
	      __imag__ res = __copysignf (HUGE_VALF, __imag__ x);
	    }
	  else
	    {
	      __real__ res = __real__ x;
	      __imag__ res = (icls == FP_NAN
			      ? __nanf ("") : __copysignf (0.0, __imag__ x));
	    }
	}
      else
	{
	  __real__ res = __nanf ("");
	  __imag__ res = __nanf ("");
	}
    }
  else
    {
      if (icls == FP_ZERO)
	{
	  if (__real__ x < 0.0)
	    {
	      __real__ res = 0.0;
	      __imag__ res = __copysignf (__ieee754_sqrtf (-__real__ x),
					  __imag__ x);
	    }
	  else
	    {
	      __real__ res = fabsf (__ieee754_sqrtf (__real__ x));
	      __imag__ res = __copysignf (0.0, __imag__ x);
	    }
	}
      else if (rcls == FP_ZERO)
	{
	  float r = __ieee754_sqrtf (0.5 * fabsf (__imag__ x));

	  __real__ res = __copysignf (r, __imag__ x);
	  __imag__ res = r;
	}
      else
	{
	  float d, r, s;

	  d = __ieee754_hypotf (__real__ x, __imag__ x);
	  /* Use the identity   2  Re res  Im res = Im x
	     to avoid cancellation error in  d +/- Re x.  */
	  if (__real__ x > 0)
	    {
	      r = __ieee754_sqrtf (0.5f * d + 0.5f * __real__ x);
	      s = (0.5f * __imag__ x) / r;
	    }
	  else
	    {
	      s = __ieee754_sqrtf (0.5f * d - 0.5f * __real__ x);
	      r = fabsf ((0.5f * __imag__ x) / s);
	    }

	  __real__ res = r;
	  __imag__ res = __copysignf (s, __imag__ x);
	}
    }

  return res;
}
예제 #17
0
파일: k_casinhf.c 프로젝트: Xilinx/eglibc
__complex__ float
__kernel_casinhf (__complex__ float x, int adj)
{
  __complex__ float res;
  float rx, ix;
  __complex__ float y;

  /* Avoid cancellation by reducing to the first quadrant.  */
  rx = fabsf (__real__ x);
  ix = fabsf (__imag__ x);

  if (rx >= 1.0f / FLT_EPSILON || ix >= 1.0f / FLT_EPSILON)
    {
      /* For large x in the first quadrant, x + csqrt (1 + x * x)
	 is sufficiently close to 2 * x to make no significant
	 difference to the result; avoid possible overflow from
	 the squaring and addition.  */
      __real__ y = rx;
      __imag__ y = ix;

      if (adj)
	{
	  float t = __real__ y;
	  __real__ y = __copysignf (__imag__ y, __imag__ x);
	  __imag__ y = t;
	}

      res = __clogf (y);
      __real__ res += (float) M_LN2;
    }
  else if (rx >= 0.5f && ix < FLT_EPSILON / 8.0f)
    {
      float s = __ieee754_hypotf (1.0f, rx);

      __real__ res = __ieee754_logf (rx + s);
      if (adj)
	__imag__ res = __ieee754_atan2f (s, __imag__ x);
      else
	__imag__ res = __ieee754_atan2f (ix, s);
    }
  else if (rx < FLT_EPSILON / 8.0f && ix >= 1.5f)
    {
      float s = __ieee754_sqrtf ((ix + 1.0f) * (ix - 1.0f));

      __real__ res = __ieee754_logf (ix + s);
      if (adj)
	__imag__ res = __ieee754_atan2f (rx, __copysignf (s, __imag__ x));
      else
	__imag__ res = __ieee754_atan2f (s, rx);
    }
  else if (ix > 1.0f && ix < 1.5f && rx < 0.5f)
    {
      if (rx < FLT_EPSILON * FLT_EPSILON)
	{
	  float ix2m1 = (ix + 1.0f) * (ix - 1.0f);
	  float s = __ieee754_sqrtf (ix2m1);

	  __real__ res = __log1pf (2.0f * (ix2m1 + ix * s)) / 2.0f;
	  if (adj)
	    __imag__ res = __ieee754_atan2f (rx, __copysignf (s, __imag__ x));
	  else
	    __imag__ res = __ieee754_atan2f (s, rx);
	}
      else
	{
	  float ix2m1 = (ix + 1.0f) * (ix - 1.0f);
	  float rx2 = rx * rx;
	  float f = rx2 * (2.0f + rx2 + 2.0f * ix * ix);
	  float d = __ieee754_sqrtf (ix2m1 * ix2m1 + f);
	  float dp = d + ix2m1;
	  float dm = f / dp;
	  float r1 = __ieee754_sqrtf ((dm + rx2) / 2.0f);
	  float r2 = rx * ix / r1;

	  __real__ res
	    = __log1pf (rx2 + dp + 2.0f * (rx * r1 + ix * r2)) / 2.0f;
	  if (adj)
	    __imag__ res = __ieee754_atan2f (rx + r1, __copysignf (ix + r2,
								   __imag__ x));
	  else
	    __imag__ res = __ieee754_atan2f (ix + r2, rx + r1);
	}
    }
  else if (ix == 1.0f && rx < 0.5f)
    {
      if (rx < FLT_EPSILON / 8.0f)
	{
	  __real__ res = __log1pf (2.0f * (rx + __ieee754_sqrtf (rx))) / 2.0f;
	  if (adj)
	    __imag__ res = __ieee754_atan2f (__ieee754_sqrtf (rx),
					     __copysignf (1.0f, __imag__ x));
	  else
	    __imag__ res = __ieee754_atan2f (1.0f, __ieee754_sqrtf (rx));
	}
      else
	{
	  float d = rx * __ieee754_sqrtf (4.0f + rx * rx);
	  float s1 = __ieee754_sqrtf ((d + rx * rx) / 2.0f);
	  float s2 = __ieee754_sqrtf ((d - rx * rx) / 2.0f);

	  __real__ res = __log1pf (rx * rx + d + 2.0f * (rx * s1 + s2)) / 2.0f;
	  if (adj)
	    __imag__ res = __ieee754_atan2f (rx + s1,
					     __copysignf (1.0f + s2,
							  __imag__ x));
	  else
	    __imag__ res = __ieee754_atan2f (1.0f + s2, rx + s1);
	}
    }
  else if (ix < 1.0f && rx < 0.5f)
    {
      if (ix >= FLT_EPSILON)
	{
	  if (rx < FLT_EPSILON * FLT_EPSILON)
	    {
	      float onemix2 = (1.0f + ix) * (1.0f - ix);
	      float s = __ieee754_sqrtf (onemix2);

	      __real__ res = __log1pf (2.0f * rx / s) / 2.0f;
	      if (adj)
		__imag__ res = __ieee754_atan2f (s, __imag__ x);
	      else
		__imag__ res = __ieee754_atan2f (ix, s);
	    }
	  else
	    {
	      float onemix2 = (1.0f + ix) * (1.0f - ix);
	      float rx2 = rx * rx;
	      float f = rx2 * (2.0f + rx2 + 2.0f * ix * ix);
	      float d = __ieee754_sqrtf (onemix2 * onemix2 + f);
	      float dp = d + onemix2;
	      float dm = f / dp;
	      float r1 = __ieee754_sqrtf ((dp + rx2) / 2.0f);
	      float r2 = rx * ix / r1;

	      __real__ res
		= __log1pf (rx2 + dm + 2.0f * (rx * r1 + ix * r2)) / 2.0f;
	      if (adj)
		__imag__ res = __ieee754_atan2f (rx + r1,
						 __copysignf (ix + r2,
							      __imag__ x));
	      else
		__imag__ res = __ieee754_atan2f (ix + r2, rx + r1);
	    }
	}
      else
	{
	  float s = __ieee754_hypotf (1.0f, rx);

	  __real__ res = __log1pf (2.0f * rx * (rx + s)) / 2.0f;
	  if (adj)
	    __imag__ res = __ieee754_atan2f (s, __imag__ x);
	  else
	    __imag__ res = __ieee754_atan2f (ix, s);
	}
      if (__real__ res < FLT_MIN)
	{
	  volatile float force_underflow = __real__ res * __real__ res;
	  (void) force_underflow;
	}
    }
  else
    {
      __real__ y = (rx - ix) * (rx + ix) + 1.0f;
      __imag__ y = 2.0f * rx * ix;

      y = __csqrtf (y);

      __real__ y += rx;
      __imag__ y += ix;

      if (adj)
	{
	  float t = __real__ y;
	  __real__ y = __copysignf (__imag__ y, __imag__ x);
	  __imag__ y = t;
	}

      res = __clogf (y);
    }

  /* Give results the correct sign for the original argument.  */
  __real__ res = __copysignf (__real__ res, __real__ x);
  __imag__ res = __copysignf (__imag__ res, (adj ? 1.0f : __imag__ x));

  return res;
}
예제 #18
0
파일: hypot.cpp 프로젝트: chenbk85/QOR
    //------------------------------------------------------------------------------
    float Cmath::__ieee754_hypotf( float x, float y )
    {
        float a = x, b = y, t1, t2, y1, y2, w;
        Cmp_signed__int32 j, k, ha, hb;

        get_float_word( ha, x );
        ha &= 0x7fffffffL;
        get_float_word( hb, y );
        hb &= 0x7fffffffL;
        if( hb > ha )
        {
            a = y;
            b = x;
            j = ha;
            ha = hb;
            hb = j;
        }
        else
        {
            a = x;
            b = y;
        }

        set_float_word( a, ha ); // a <- |a|
        set_float_word( b, hb ); // b <- |b|
        if( ( ha - hb ) > 0xf000000L )
        {
            return a + b; // x/y > 2**30
        }

        k = 0;
        if( ha > 0x58800000L )
        {
            // a>2**50
            if( !uword_isfinite( ha ) )
            {
                // Inf or NaN
                w = a + b; // for sNaN
                if( uword_is_infinite( ha ) )
                {
                    w = a;
                }

                if( uword_is_infinite( hb ) )
                {
                    w = b;
                }
                return w;
            }
            // scale a and b by 2**-68
            ha -= 0x22000000L;
            hb -= 0x22000000L;
            k += 68;
            set_float_word( a, ha );
            set_float_word( b, hb );
        }

        if( hb < 0x26800000L )
        {
            // b < 2**-50
            if( uword_is_zero( hb ) )
            {
                return a;
            }
            else if( uword_is_subnormal( hb ) )
            {
                set_float_word( t1, 0x7e800000L ); // t1=2^126
                b *= t1;
                a *= t1;
                k -= 126;
            }
            else
            {
                // scale a and b by 2^68
                ha += 0x22000000; 	// a *= 2^68
                hb += 0x22000000;	// b *= 2^68
                k -= 68;
                set_float_word( a, ha );
                set_float_word( b, hb );
            }
        }

        // medium size a and b
        w = a - b;
        if( w > b )
        {
            set_float_word( t1, ha & 0xfffff000L );
            t2 = a - t1;
            w  = __ieee754_sqrtf( t1 * t1 - ( b * (-b) - t2 * ( a + t1 ) ) );
        }
        else
        {
            a = a + a;
            set_float_word( y1, hb & 0xfffff000L );
            y2 = b - y1;
            set_float_word( t1, ha + 0x00800000L );
            t2 = a - t1;
            w  = __ieee754_sqrtf( t1 * y1 - ( w * (-w) - ( t1 * y2 + t2 * b ) ) );
        }

        if( k != 0 )
        {
            set_float_word( t1, 0x3f800000L + ( k << 23 ) );
            return t1 * w;
        }
        else
        {
            return w;
        }
    }
예제 #19
0
파일: e_hypotf.c 프로젝트: efidroid/edk2
float
__ieee754_hypotf(float x, float y)
{
	float a=x,b=y,t1,t2,y1,y2,w;
	int32_t j,k,ha,hb;

	GET_FLOAT_WORD(ha,x);
	ha &= 0x7fffffff;
	GET_FLOAT_WORD(hb,y);
	hb &= 0x7fffffff;
	if(hb > ha) {a=y;b=x;j=ha; ha=hb;hb=j;} else {a=x;b=y;}
	SET_FLOAT_WORD(a,ha);	/* a <- |a| */
	SET_FLOAT_WORD(b,hb);	/* b <- |b| */
	if((ha-hb)>0xf000000) {return a+b;} /* x/y > 2**30 */
	k=0;
	if(ha > 0x58800000) {	/* a>2**50 */
	   if(ha >= 0x7f800000) {	/* Inf or NaN */
	       w = a+b;			/* for sNaN */
	       if(ha == 0x7f800000) w = a;
	       if(hb == 0x7f800000) w = b;
	       return w;
	   }
	   /* scale a and b by 2**-60 */
	   ha -= 0x5d800000; hb -= 0x5d800000;	k += 60;
	   SET_FLOAT_WORD(a,ha);
	   SET_FLOAT_WORD(b,hb);
	}
	if(hb < 0x26800000) {	/* b < 2**-50 */
	    if(hb <= 0x007fffff) {	/* subnormal b or 0 */
	        if(hb==0) return a;
		SET_FLOAT_WORD(t1,0x3f000000);	/* t1=2^126 */
		b *= t1;
		a *= t1;
		k -= 126;
	    } else {		/* scale a and b by 2^60 */
	        ha += 0x5d800000; 	/* a *= 2^60 */
		hb += 0x5d800000;	/* b *= 2^60 */
		k -= 60;
		SET_FLOAT_WORD(a,ha);
		SET_FLOAT_WORD(b,hb);
	    }
	}
    /* medium size a and b */
	w = a-b;
	if (w>b) {
	    SET_FLOAT_WORD(t1,ha&0xfffff000);
	    t2 = a-t1;
	    w  = __ieee754_sqrtf(t1*t1-(b*(-b)-t2*(a+t1)));
	} else {
	    a  = a+a;
	    SET_FLOAT_WORD(y1,hb&0xfffff000);
	    y2 = b - y1;
	    SET_FLOAT_WORD(t1,ha+0x00800000);
	    t2 = a - t1;
	    w  = __ieee754_sqrtf(t1*y1-(w*(-w)-(t1*y2+t2*b)));
	}
	if(k!=0) {
	    SET_FLOAT_WORD(t1,0x3f800000+(k<<23));
	    return t1*w;
	} else return w;
}
예제 #20
0
OLM_DLLEXPORT float
__ieee754_hypotf(float x, float y)
{
	float a,b,t1,t2,y1,y2,w;
	int32_t j,k,ha,hb;

	GET_FLOAT_WORD(ha,x);
	ha &= 0x7fffffff;
	GET_FLOAT_WORD(hb,y);
	hb &= 0x7fffffff;
	if(hb > ha) {a=y;b=x;j=ha; ha=hb;hb=j;} else {a=x;b=y;}
	a = fabsf(a);
	b = fabsf(b);
	if((ha-hb)>0xf000000) {return a+b;} /* x/y > 2**30 */
	k=0;
	if(ha > 0x58800000) {	/* a>2**50 */
	   if(ha >= 0x7f800000) {	/* Inf or NaN */
	       /* Use original arg order iff result is NaN; quieten sNaNs. */
	       w = fabsf(x+0.0F)-fabsf(y+0.0F);
	       if(ha == 0x7f800000) w = a;
	       if(hb == 0x7f800000) w = b;
	       return w;
	   }
	   /* scale a and b by 2**-68 */
	   ha -= 0x22000000; hb -= 0x22000000;	k += 68;
	   SET_FLOAT_WORD(a,ha);
	   SET_FLOAT_WORD(b,hb);
	}
	if(hb < 0x26800000) {	/* b < 2**-50 */
	    if(hb <= 0x007fffff) {	/* subnormal b or 0 */
	        if(hb==0) return a;
		SET_FLOAT_WORD(t1,0x7e800000);	/* t1=2^126 */
		b *= t1;
		a *= t1;
		k -= 126;
	    } else {		/* scale a and b by 2^68 */
	        ha += 0x22000000; 	/* a *= 2^68 */
		hb += 0x22000000;	/* b *= 2^68 */
		k -= 68;
		SET_FLOAT_WORD(a,ha);
		SET_FLOAT_WORD(b,hb);
	    }
	}
    /* medium size a and b */
	w = a-b;
	if (w>b) {
	    SET_FLOAT_WORD(t1,ha&0xfffff000);
	    t2 = a-t1;
	    w  = __ieee754_sqrtf(t1*t1-(b*(-b)-t2*(a+t1)));
	} else {
	    a  = a+a;
	    SET_FLOAT_WORD(y1,hb&0xfffff000);
	    y2 = b - y1;
	    SET_FLOAT_WORD(t1,(ha+0x00800000)&0xfffff000);
	    t2 = a - t1;
	    w  = __ieee754_sqrtf(t1*y1-(w*(-w)-(t1*y2+t2*b)));
	}
	if(k!=0) {
	    SET_FLOAT_WORD(t1,0x3f800000+(k<<23));
	    return t1*w;
	} else return w;
}
예제 #21
0
static float
gammaf_positive (float x, int *exp2_adj)
{
  int local_signgam;
  if (x < 0.5f)
    {
      *exp2_adj = 0;
      return __ieee754_expf (__ieee754_lgammaf_r (x + 1, &local_signgam)) / x;
    }
  else if (x <= 1.5f)
    {
      *exp2_adj = 0;
      return __ieee754_expf (__ieee754_lgammaf_r (x, &local_signgam));
    }
  else if (x < 2.5f)
    {
      *exp2_adj = 0;
      float x_adj = x - 1;
      return (__ieee754_expf (__ieee754_lgammaf_r (x_adj, &local_signgam))
	      * x_adj);
    }
  else
    {
      float eps = 0;
      float x_eps = 0;
      float x_adj = x;
      float prod = 1;
      if (x < 4.0f)
	{
	  /* Adjust into the range for applying Stirling's
	     approximation.  */
	  float n = __ceilf (4.0f - x);
	  x_adj = math_narrow_eval (x + n);
	  x_eps = (x - (x_adj - n));
	  prod = __gamma_productf (x_adj - n, x_eps, n, &eps);
	}
      /* The result is now gamma (X_ADJ + X_EPS) / (PROD * (1 + EPS)).
	 Compute gamma (X_ADJ + X_EPS) using Stirling's approximation,
	 starting by computing pow (X_ADJ, X_ADJ) with a power of 2
	 factored out.  */
      float exp_adj = -eps;
      float x_adj_int = __roundf (x_adj);
      float x_adj_frac = x_adj - x_adj_int;
      int x_adj_log2;
      float x_adj_mant = __frexpf (x_adj, &x_adj_log2);
      if (x_adj_mant < (float) M_SQRT1_2)
	{
	  x_adj_log2--;
	  x_adj_mant *= 2.0f;
	}
      *exp2_adj = x_adj_log2 * (int) x_adj_int;
      float ret = (__ieee754_powf (x_adj_mant, x_adj)
		   * __ieee754_exp2f (x_adj_log2 * x_adj_frac)
		   * __ieee754_expf (-x_adj)
		   * __ieee754_sqrtf (2 * (float) M_PI / x_adj)
		   / prod);
      exp_adj += x_eps * __ieee754_logf (x_adj);
      float bsum = gamma_coeff[NCOEFF - 1];
      float x_adj2 = x_adj * x_adj;
      for (size_t i = 1; i <= NCOEFF - 1; i++)
	bsum = bsum / x_adj2 + gamma_coeff[NCOEFF - 1 - i];
      exp_adj += bsum / x_adj;
      return ret + ret * __expm1f (exp_adj);
    }
}