示例#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
文件: e_j0f.c 项目: HuaiYuSched/pok
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  */
	if(ix>=0x7f800000) return  one/(x+x*x);
        if(ix==0) return -one/zero;
        if(hx<0) return zero/zero;
        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.
         */
                s = sinf(x);
                c = cosf(x);
                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;
                }
#ifdef DEAD_CODE
                if(ix>0x80000000) z = (invsqrtpi*ss)/sqrtf(x);
                else
#endif
		{
                    u = pzerof(x); v = qzerof(x);
                    z = invsqrtpi*(u*ss+v*cc)/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)));
}
示例#3
0
__complex__ float
__catanhf (__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 = __copysignf (0.0, __real__ x);
	  __imag__ res = __copysignf (M_PI_2, __imag__ x);
	}
      else if (rcls == FP_INFINITE || rcls == FP_ZERO)
	{
	  __real__ res = __copysignf (0.0, __real__ x);
	  if (icls >= FP_ZERO)
	    __imag__ res = __copysignf (M_PI_2, __imag__ x);
	  else
	    __imag__ res = __nanf ("");
	}
      else
	{
	  __real__ res = __nanf ("");
	  __imag__ res = __nanf ("");
	}
    }
  else if (__builtin_expect (rcls == FP_ZERO && icls == FP_ZERO, 0))
    {
      res = x;
    }
  else
    {
      float i2 = __imag__ x * __imag__ x;

      float num = 1.0 + __real__ x;
      num = i2 + num * num;

      float den = 1.0 - __real__ x;
      den = i2 + den * den;

      __real__ res = 0.25 * (__ieee754_logf (num) - __ieee754_logf (den));

      den = 1 - __real__ x * __real__ x - i2;

      __imag__ res = 0.5 * __ieee754_atan2f (2.0 * __imag__ x, den);
    }

  return res;
}
示例#4
0
文件: s_clogf.c 项目: dreal/tai
__complex__ float
__clogf (__complex__ float x)
{
  __complex__ float result;
  int rcls = fpclassify (__real__ x);
  int icls = fpclassify (__imag__ x);

  if (__builtin_expect (rcls == FP_ZERO && icls == FP_ZERO, 0))
    {
      /* Real and imaginary part are 0.0.  */
      __imag__ result = signbit (__real__ x) ? M_PI : 0.0;
      __imag__ result = __copysignf (__imag__ result, __imag__ x);
      /* Yes, the following line raises an exception.  */
      __real__ result = -1.0 / fabsf (__real__ x);
    }
  else if (__builtin_expect (rcls != FP_NAN && icls != FP_NAN, 1))
    {
      /* Neither real nor imaginary part is NaN.  */
      __real__ result = __ieee754_logf (__ieee754_hypotf (__real__ x,
							  __imag__ x));
      __imag__ result = __ieee754_atan2f (__imag__ x, __real__ x);
    }
  else
    {
      __imag__ result = __nanf ("");
      if (rcls == FP_INFINITE || icls == FP_INFINITE)
	/* Real or imaginary part is infinite.  */
	__real__ result = HUGE_VALF;
      else
	__real__ result = __nanf ("");
    }

  return result;
}
示例#5
0
float
__ieee754_log10f(float x)
{
	float y,z;
	int32_t i,k,hx;

	GET_FLOAT_WORD(hx,x);

        k=0;
        if (hx < 0x00800000) {                  /* x < 2**-126  */
            if ((hx&0x7fffffff)==0)
                return -two25/zero;             /* log(+-0)=-inf */
            if (hx<0) return (x-x)/zero;        /* log(-#) = NaN */
            k -= 25; x *= two25; /* subnormal number, scale up x */
	    GET_FLOAT_WORD(hx,x);
        }
	if (hx >= 0x7f800000) return x+x;
	k += (hx>>23)-127;
	i  = ((u_int32_t)k&0x80000000)>>31;
        hx = (hx&0x007fffff)|((0x7f-i)<<23);
        y  = (float)(k+i);
	SET_FLOAT_WORD(x,hx);
	z  = y*log10_2lo + ivln10*__ieee754_logf(x);
	return  z+y*log10_2hi;
}
示例#6
0
float
logf(float x)		/* wrapper logf */
{
#ifdef _IEEE_LIBM
	return __ieee754_logf(x);
#else
	float z;
	z = __ieee754_logf(x);
	if(_LIB_VERSION == _IEEE_ || isnanf(x) || x > (float)0.0) return z;
	if(x==(float)0.0)
	    /* logf(0) */
	    return (float)__kernel_standard((double)x,(double)x,116);
	else
	    /* logf(x<0) */
	    return (float)__kernel_standard((double)x,(double)x,117);
#endif
}
示例#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
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));
}
示例#9
0
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;
}
示例#10
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));
	}
}
示例#11
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(ix>=0x7f800000) return  one/(x+x*x);
        if(ix==0) return -one/zero;
        if(hx<0) return zero/zero;
        if(ix >= 0x40000000) {  /* |x| >= 2.0 */
                s = sinf(x);
                c = cosf(x);
                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)/sqrtf(x);
                else {
                    u = ponef(x); v = qonef(x);
                    z = invsqrtpi*(u*ss+v*cc)/sqrtf(x);
                }
                return z;
        }
        if(ix<=0x24800000) {    /* x < 2**-54 */
            return(-tpi/x);
        }
        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));
}
int main() {

  /* REQ-BL-0910
   * The log and logf procedures shall return -Inf if the argument x is +-0.
   */

  float x = -0.0f;
  float res = __ieee754_logf(x);

  // x is -0, the result shall be -inf
  if (!isinf_float(res)) {
    __VERIFIER_error();
    return 1;
  }
  return 0;
}
示例#13
0
文件: w_logf.c 项目: endplay/omniplay
/* wrapper logf(x) */
float
__logf (float x)
{
  if (__builtin_expect (x <= 0.0f, 0) && _LIB_VERSION != _IEEE_)
    {
      if (x == 0.0f)
	{
	  feraiseexcept (FE_DIVBYZERO);
	  return __kernel_standard_f (x, x, 116); /* log(0) */
	}
      else
	{
	  feraiseexcept (FE_INVALID);
	  return __kernel_standard_f (x, x, 117); /* log(x<0) */
	}
    }

  return  __ieee754_logf (x);
}
float __ieee754_log10f(float x) {
  float y, z;
  __int32_t i, k, hx;

  do {
    ieee_float_shape_type gf_u;
    gf_u.value = (x);
    (hx) = gf_u.word;
  } while (0);

  k = 0;
  if (((hx & 0x7fffffff) == 0))
    return -two25_log10 / zero;
  if (hx < 0)
    return (x - x) / zero;
  if (!((hx) < 0x7f800000L))
    return x + x;
  if (((hx) < 0x00800000L)) {
    k -= 25;
    x *= two25_log10;
    do {
      ieee_float_shape_type gf_u;
      gf_u.value = (x);
      (hx) = gf_u.word;
    } while (0);
  }
  k += (hx >> 23) - 127;
  i = ((__uint32_t)k & 0x80000000) >> 31;
  hx = (hx & 0x007fffff) | ((0x7f - i) << 23);
  y = (float)(k + i);
  do {
    ieee_float_shape_type sf_u;
    sf_u.word = (hx);
    (x) = sf_u.value;
  } while (0);
  z = y * log10_2lo_log10 + ivln10_log10 * __ieee754_logf(x);
  return z + y * log10_2hi_log10;
}
示例#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
float
__ieee754_lgammaf_r(float x, int *signgamp)
{
	float t,y,z,nadj,p,p1,p2,p3,q,r,w;
	int i,hx,ix;

	GET_FLOAT_WORD(hx,x);

    /* purge off +-inf, NaN, +-0, and negative arguments */
	*signgamp = 1;
	ix = hx&0x7fffffff;
	if(__builtin_expect(ix>=0x7f800000, 0)) return x*x;
	if(__builtin_expect(ix==0, 0))
	  {
	    if (hx < 0)
	      *signgamp = -1;
	    return one/fabsf(x);
	  }
	if(__builtin_expect(ix<0x30800000, 0)) {
	    /* |x|<2**-30, return -log(|x|) */
	    if(hx<0) {
		*signgamp = -1;
		return -__ieee754_logf(-x);
	    } else return -__ieee754_logf(x);
	}
	if(hx<0) {
	    if(ix>=0x4b000000)	/* |x|>=2**23, must be -integer */
		return x/zero;
	    if (ix > 0x40000000 /* X < 2.0f.  */
		&& ix < 0x41700000 /* X > -15.0f.  */)
		return __lgamma_negf (x, signgamp);
	    t = sin_pif(x);
	    if(t==zero) return one/fabsf(t); /* -integer */
	    nadj = __ieee754_logf(pi/fabsf(t*x));
	    if(t<zero) *signgamp = -1;
	    x = -x;
	}

    /* purge off 1 and 2 */
	if (ix==0x3f800000||ix==0x40000000) r = 0;
    /* for x < 2.0 */
	else if(ix<0x40000000) {
	    if(ix<=0x3f666666) {	/* lgamma(x) = lgamma(x+1)-log(x) */
		r = -__ieee754_logf(x);
		if(ix>=0x3f3b4a20) {y = one-x; i= 0;}
		else if(ix>=0x3e6d3308) {y= x-(tc-one); i=1;}
		else {y = x; i=2;}
	    } else {
		r = zero;
		if(ix>=0x3fdda618) {y=(float)2.0-x;i=0;} /* [1.7316,2] */
		else if(ix>=0x3F9da620) {y=x-tc;i=1;} /* [1.23,1.73] */
		else {y=x-one;i=2;}
	    }
	    switch(i) {
	      case 0:
		z = y*y;
		p1 = a0+z*(a2+z*(a4+z*(a6+z*(a8+z*a10))));
		p2 = z*(a1+z*(a3+z*(a5+z*(a7+z*(a9+z*a11)))));
		p  = y*p1+p2;
		r  += (p-(float)0.5*y); break;
	      case 1:
		z = y*y;
		w = z*y;
		p1 = t0+w*(t3+w*(t6+w*(t9 +w*t12)));	/* parallel comp */
		p2 = t1+w*(t4+w*(t7+w*(t10+w*t13)));
		p3 = t2+w*(t5+w*(t8+w*(t11+w*t14)));
		p  = z*p1-(tt-w*(p2+y*p3));
		r += (tf + p); break;
	      case 2:
		p1 = y*(u0+y*(u1+y*(u2+y*(u3+y*(u4+y*u5)))));
		p2 = one+y*(v1+y*(v2+y*(v3+y*(v4+y*v5))));
		r += (-(float)0.5*y + p1/p2);
	    }
	}
	else if(ix<0x41000000) {			/* x < 8.0 */
	    i = (int)x;
	    t = zero;
	    y = x-(float)i;
	    p = y*(s0+y*(s1+y*(s2+y*(s3+y*(s4+y*(s5+y*s6))))));
	    q = one+y*(r1+y*(r2+y*(r3+y*(r4+y*(r5+y*r6)))));
	    r = half*y+p/q;
	    z = one;	/* lgamma(1+s) = log(s) + lgamma(s) */
	    switch(i) {
	    case 7: z *= (y+(float)6.0);	/* FALLTHRU */
	    case 6: z *= (y+(float)5.0);	/* FALLTHRU */
	    case 5: z *= (y+(float)4.0);	/* FALLTHRU */
	    case 4: z *= (y+(float)3.0);	/* FALLTHRU */
	    case 3: z *= (y+(float)2.0);	/* FALLTHRU */
		    r += __ieee754_logf(z); break;
	    }
    /* 8.0 <= x < 2**26 */
	} else if (ix < 0x4c800000) {
	    t = __ieee754_logf(x);
	    z = one/x;
	    y = z*z;
	    w = w0+z*(w1+y*(w2+y*(w3+y*(w4+y*(w5+y*w6)))));
	    r = (x-half)*(t-one)+w;
	} else
    /* 2**26 <= x <= inf */
	    r =  math_narrow_eval (x*(__ieee754_logf(x)-one));
	/* NADJ is set for negative arguments but not otherwise,
	   resulting in warnings that it may be used uninitialized
	   although in the cases where it is used it has always been
	   set.  */
	DIAG_PUSH_NEEDS_COMMENT;
#if __GNUC_PREREQ (4, 7)
	DIAG_IGNORE_NEEDS_COMMENT (4.9, "-Wmaybe-uninitialized");
#else
	DIAG_IGNORE_NEEDS_COMMENT (4.9, "-Wuninitialized");
#endif
	if(hx<0) r = nadj - r;
	DIAG_POP_NEEDS_COMMENT;
	return r;
}
示例#17
0
float
__lgamma_negf (float x, int *signgamp)
{
  /* Determine the half-integer region X lies in, handle exact
     integers and determine the sign of the result.  */
  int i = __floorf (-2 * x);
  if ((i & 1) == 0 && i == -2 * x)
    return 1.0f / 0.0f;
  float xn = ((i & 1) == 0 ? -i / 2 : (-i - 1) / 2);
  i -= 4;
  *signgamp = ((i & 2) == 0 ? -1 : 1);

  SET_RESTORE_ROUNDF (FE_TONEAREST);

  /* Expand around the zero X0 = X0_HI + X0_LO.  */
  float x0_hi = lgamma_zeros[i][0], x0_lo = lgamma_zeros[i][1];
  float xdiff = x - x0_hi - x0_lo;

  /* For arguments in the range -3 to -2, use polynomial
     approximations to an adjusted version of the gamma function.  */
  if (i < 2)
    {
      int j = __floorf (-8 * x) - 16;
      float xm = (-33 - 2 * j) * 0.0625f;
      float x_adj = x - xm;
      size_t deg = poly_deg[j];
      size_t end = poly_end[j];
      float g = poly_coeff[end];
      for (size_t j = 1; j <= deg; j++)
	g = g * x_adj + poly_coeff[end - j];
      return __log1pf (g * xdiff / (x - xn));
    }

  /* The result we want is log (sinpi (X0) / sinpi (X))
     + log (gamma (1 - X0) / gamma (1 - X)).  */
  float x_idiff = fabsf (xn - x), x0_idiff = fabsf (xn - x0_hi - x0_lo);
  float log_sinpi_ratio;
  if (x0_idiff < x_idiff * 0.5f)
    /* Use log not log1p to avoid inaccuracy from log1p of arguments
       close to -1.  */
    log_sinpi_ratio = __ieee754_logf (lg_sinpi (x0_idiff)
				      / lg_sinpi (x_idiff));
  else
    {
      /* Use log1p not log to avoid inaccuracy from log of arguments
	 close to 1.  X0DIFF2 has positive sign if X0 is further from
	 XN than X is from XN, negative sign otherwise.  */
      float x0diff2 = ((i & 1) == 0 ? xdiff : -xdiff) * 0.5f;
      float sx0d2 = lg_sinpi (x0diff2);
      float cx0d2 = lg_cospi (x0diff2);
      log_sinpi_ratio = __log1pf (2 * sx0d2
				  * (-sx0d2 + cx0d2 * lg_cotpi (x_idiff)));
    }

  float log_gamma_ratio;
  float y0 = math_narrow_eval (1 - x0_hi);
  float y0_eps = -x0_hi + (1 - y0) - x0_lo;
  float y = math_narrow_eval (1 - x);
  float y_eps = -x + (1 - y);
  /* We now wish to compute LOG_GAMMA_RATIO
     = log (gamma (Y0 + Y0_EPS) / gamma (Y + Y_EPS)).  XDIFF
     accurately approximates the difference Y0 + Y0_EPS - Y -
     Y_EPS.  Use Stirling's approximation.  */
  float log_gamma_high
    = (xdiff * __log1pf ((y0 - e_hi - e_lo + y0_eps) / e_hi)
       + (y - 0.5f + y_eps) * __log1pf (xdiff / y));
  /* Compute the sum of (B_2k / 2k(2k-1))(Y0^-(2k-1) - Y^-(2k-1)).  */
  float y0r = 1 / y0, yr = 1 / y;
  float y0r2 = y0r * y0r, yr2 = yr * yr;
  float rdiff = -xdiff / (y * y0);
  float bterm[NCOEFF];
  float dlast = rdiff, elast = rdiff * yr * (yr + y0r);
  bterm[0] = dlast * lgamma_coeff[0];
  for (size_t j = 1; j < NCOEFF; j++)
    {
      float dnext = dlast * y0r2 + elast;
      float enext = elast * yr2;
      bterm[j] = dnext * lgamma_coeff[j];
      dlast = dnext;
      elast = enext;
    }
  float log_gamma_low = 0;
  for (size_t j = 0; j < NCOEFF; j++)
    log_gamma_low += bterm[NCOEFF - 1 - j];
  log_gamma_ratio = log_gamma_high + log_gamma_low;

  return log_sinpi_ratio + log_gamma_ratio;
}
示例#18
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;
}
示例#19
0
文件: s_catanf.c 项目: alucas/glibc
__complex__ float
__catanf (__complex__ float x)
{
  __complex__ float res;
  int rcls = fpclassify (__real__ x);
  int icls = fpclassify (__imag__ x);

  if (__glibc_unlikely (rcls <= FP_INFINITE || icls <= FP_INFINITE))
    {
      if (rcls == FP_INFINITE)
	{
	  __real__ res = __copysignf (M_PI_2, __real__ x);
	  __imag__ res = __copysignf (0.0, __imag__ x);
	}
      else if (icls == FP_INFINITE)
	{
	  if (rcls >= FP_ZERO)
	    __real__ res = __copysignf (M_PI_2, __real__ x);
	  else
	    __real__ res = __nanf ("");
	  __imag__ res = __copysignf (0.0, __imag__ x);
	}
      else if (icls == FP_ZERO || icls == FP_INFINITE)
	{
	  __real__ res = __nanf ("");
	  __imag__ res = __copysignf (0.0, __imag__ x);
	}
      else
	{
	  __real__ res = __nanf ("");
	  __imag__ res = __nanf ("");
	}
    }
  else if (__glibc_unlikely (rcls == FP_ZERO && icls == FP_ZERO))
    {
      res = x;
    }
  else
    {
      if (fabsf (__real__ x) >= 16.0f / FLT_EPSILON
	  || fabsf (__imag__ x) >= 16.0f / FLT_EPSILON)
	{
	  __real__ res = __copysignf ((float) M_PI_2, __real__ x);
	  if (fabsf (__real__ x) <= 1.0f)
	    __imag__ res = 1.0f / __imag__ x;
	  else if (fabsf (__imag__ x) <= 1.0f)
	    __imag__ res = __imag__ x / __real__ x / __real__ x;
	  else
	    {
	      float h = __ieee754_hypotf (__real__ x / 2.0f,
					  __imag__ x / 2.0f);
	      __imag__ res = __imag__ x / h / h / 4.0f;
	    }
	}
      else
	{
	  float den, absx, absy;

	  absx = fabsf (__real__ x);
	  absy = fabsf (__imag__ x);
	  if (absx < absy)
	    {
	      float t = absx;
	      absx = absy;
	      absy = t;
	    }

	  if (absy < FLT_EPSILON / 2.0f)
	    {
	      den = (1.0f - absx) * (1.0f + absx);
	      if (den == -0.0f)
		den = 0.0f;
	    }
	  else if (absx >= 1.0f)
	    den = (1.0f - absx) * (1.0f + absx) - absy * absy;
	  else if (absx >= 0.75f || absy >= 0.5f)
	    den = -__x2y2m1f (absx, absy);
	  else
	    den = (1.0f - absx) * (1.0f + absx) - absy * absy;

	  __real__ res = 0.5f * __ieee754_atan2f (2.0f * __real__ x, den);

	  if (fabsf (__imag__ x) == 1.0f
	      && fabsf (__real__ x) < FLT_EPSILON * FLT_EPSILON)
	    __imag__ res = (__copysignf (0.5f, __imag__ x)
			    * ((float) M_LN2
			       - __ieee754_logf (fabsf (__real__ x))));
	  else
	    {
	      float r2 = 0.0f, num, f;

	      if (fabsf (__real__ x) >= FLT_EPSILON * FLT_EPSILON)
		r2 = __real__ x * __real__ x;

	      num = __imag__ x + 1.0f;
	      num = r2 + num * num;

	      den = __imag__ x - 1.0f;
	      den = r2 + den * den;

	      f = num / den;
	      if (f < 0.5f)
		__imag__ res = 0.25f * __ieee754_logf (f);
	      else
		{
		  num = 4.0f * __imag__ x;
		  __imag__ res = 0.25f * __log1pf (num / den);
		}
	    }
	}

      if (fabsf (__real__ res) < FLT_MIN)
	{
	  volatile float force_underflow = __real__ res * __real__ res;
	  (void) force_underflow;
	}
      if (fabsf (__imag__ res) < FLT_MIN)
	{
	  volatile float force_underflow = __imag__ res * __imag__ res;
	  (void) force_underflow;
	}
    }

  return res;
}
示例#20
0
文件: e_lgammaf_r.c 项目: GRDSP/grdsp
float
__ieee754_lgammaf_r(float x, int *signgamp)
{
	float t,y,z,nadj,p,p1,p2,p3,q,r,w;
	int32_t hx;
	int i,ix;

	GET_FLOAT_WORD(hx,x);

    /* purge off +-inf, NaN, +-0, tiny and negative arguments */
	*signgamp = 1;
	ix = hx&0x7fffffff;
	if(ix>=0x7f800000) return x*x;
	if(ix==0) return one/zero;
	if(ix<0x35000000) {	/* |x|<2**-21, return -log(|x|) */
	    if(hx<0) {
	        *signgamp = -1;
	        return -__ieee754_logf(-x);
	    } else return -__ieee754_logf(x);
	}
	if(hx<0) {
	    if(ix>=0x4b000000) 	/* |x|>=2**23, must be -integer */
		return one/zero;
	    t = sin_pif(x);
	    if(t==zero) return one/zero; /* -integer */
	    nadj = __ieee754_logf(pi/fabsf(t*x));
	    if(t<zero) *signgamp = -1;
	    x = -x;
	}

    /* purge off 1 and 2 */
	if (ix==0x3f800000||ix==0x40000000) r = 0;
    /* for x < 2.0 */
	else if(ix<0x40000000) {
	    if(ix<=0x3f666666) { 	/* lgamma(x) = lgamma(x+1)-log(x) */
		r = -__ieee754_logf(x);
		if(ix>=0x3f3b4a20) {y = one-x; i= 0;}
		else if(ix>=0x3e6d3308) {y= x-(tc-one); i=1;}
	  	else {y = x; i=2;}
	    } else {
	  	r = zero;
	        if(ix>=0x3fdda618) {y=(float)2.0-x;i=0;} /* [1.7316,2] */
	        else if(ix>=0x3F9da620) {y=x-tc;i=1;} /* [1.23,1.73] */
		else {y=x-one;i=2;}
	    }
	    switch(i) {
	      case 0:
		z = y*y;
		p1 = a0+z*(a2+z*(a4+z*(a6+z*(a8+z*a10))));
		p2 = z*(a1+z*(a3+z*(a5+z*(a7+z*(a9+z*a11)))));
		p  = y*p1+p2;
		r  += (p-(float)0.5*y); break;
	      case 1:
		z = y*y;
		w = z*y;
		p1 = t0+w*(t3+w*(t6+w*(t9 +w*t12)));	/* parallel comp */
		p2 = t1+w*(t4+w*(t7+w*(t10+w*t13)));
		p3 = t2+w*(t5+w*(t8+w*(t11+w*t14)));
		p  = z*p1-(tt-w*(p2+y*p3));
		r += (tf + p); break;
	      case 2:
		p1 = y*(u0+y*(u1+y*(u2+y*(u3+y*(u4+y*u5)))));
		p2 = one+y*(v1+y*(v2+y*(v3+y*(v4+y*v5))));
		r += (-(float)0.5*y + p1/p2);
	    }
	}
	else if(ix<0x41000000) { 			/* x < 8.0 */
	    i = (int)x;
	    y = x-(float)i;
	    p = y*(s0+y*(s1+y*(s2+y*(s3+y*(s4+y*(s5+y*s6))))));
	    q = one+y*(r1+y*(r2+y*(r3+y*(r4+y*(r5+y*r6)))));
	    r = half*y+p/q;
	    z = one;	/* lgamma(1+s) = log(s) + lgamma(s) */
	    switch(i) {
	    case 7: z *= (y+(float)6.0);	/* FALLTHRU */
	    case 6: z *= (y+(float)5.0);	/* FALLTHRU */
	    case 5: z *= (y+(float)4.0);	/* FALLTHRU */
	    case 4: z *= (y+(float)3.0);	/* FALLTHRU */
	    case 3: z *= (y+(float)2.0);	/* FALLTHRU */
		    r += __ieee754_logf(z); break;
	    }
    /* 8.0 <= x < 2**58 */
	} else if (ix < 0x5c800000) {
	    t = __ieee754_logf(x);
	    z = one/x;
	    y = z*z;
	    w = w0+z*(w1+y*(w2+y*(w3+y*(w4+y*(w5+y*w6)))));
	    r = (x-half)*(t-one)+w;
	} else
    /* 2**58 <= x <= inf */
	    r =  x*(__ieee754_logf(x)-one);
	if(hx<0) r = nadj - r;
	return r;
}
示例#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);
    }
}
示例#22
0
文件: s_clogf.c 项目: Xilinx/eglibc
__complex__ float
__clogf (__complex__ float x)
{
  __complex__ float result;
  int rcls = fpclassify (__real__ x);
  int icls = fpclassify (__imag__ x);

  if (__builtin_expect (rcls == FP_ZERO && icls == FP_ZERO, 0))
    {
      /* Real and imaginary part are 0.0.  */
      __imag__ result = signbit (__real__ x) ? M_PI : 0.0;
      __imag__ result = __copysignf (__imag__ result, __imag__ x);
      /* Yes, the following line raises an exception.  */
      __real__ result = -1.0 / fabsf (__real__ x);
    }
  else if (__builtin_expect (rcls != FP_NAN && icls != FP_NAN, 1))
    {
      /* Neither real nor imaginary part is NaN.  */
      float absx = fabsf (__real__ x), absy = fabsf (__imag__ x);
      int scale = 0;

      if (absx < absy)
	{
	  float t = absx;
	  absx = absy;
	  absy = t;
	}

      if (absx > FLT_MAX / 2.0f)
	{
	  scale = -1;
	  absx = __scalbnf (absx, scale);
	  absy = (absy >= FLT_MIN * 2.0f ? __scalbnf (absy, scale) : 0.0f);
	}
      else if (absx < FLT_MIN && absy < FLT_MIN)
	{
	  scale = FLT_MANT_DIG;
	  absx = __scalbnf (absx, scale);
	  absy = __scalbnf (absy, scale);
	}

      if (absx == 1.0f && scale == 0)
	{
	  float absy2 = absy * absy;
	  if (absy2 <= FLT_MIN * 2.0f)
	    {
#if __FLT_EVAL_METHOD__ == 0
	      __real__ result = absy2 / 2.0f - absy2 * absy2 / 4.0f;
#else
	      volatile float force_underflow = absy2 * absy2 / 4.0f;
	      __real__ result = absy2 / 2.0f - force_underflow;
#endif
	    }
	  else
	    __real__ result = __log1pf (absy2) / 2.0f;
	}
      else if (absx > 1.0f && absx < 2.0f && absy < 1.0f && scale == 0)
	{
	  float d2m1 = (absx - 1.0f) * (absx + 1.0f);
	  if (absy >= FLT_EPSILON)
	    d2m1 += absy * absy;
	  __real__ result = __log1pf (d2m1) / 2.0f;
	}
      else if (absx < 1.0f
	       && absx >= 0.75f
	       && absy < FLT_EPSILON / 2.0f
	       && scale == 0)
	{
	  float d2m1 = (absx - 1.0f) * (absx + 1.0f);
	  __real__ result = __log1pf (d2m1) / 2.0f;
	}
      else if (absx < 1.0f && (absx >= 0.75f || absy >= 0.5f) && scale == 0)
	{
	  float d2m1 = __x2y2m1f (absx, absy);
	  __real__ result = __log1pf (d2m1) / 2.0f;
	}
      else
	{
	  float d = __ieee754_hypotf (absx, absy);
	  __real__ result = __ieee754_logf (d) - scale * (float) M_LN2;
	}

      __imag__ result = __ieee754_atan2f (__imag__ x, __real__ x);
    }
  else
    {
      __imag__ result = __nanf ("");
      if (rcls == FP_INFINITE || icls == FP_INFINITE)
	/* Real or imaginary part is infinite.  */
	__real__ result = HUGE_VALF;
      else
	__real__ result = __nanf ("");
    }

  return result;
}
示例#23
0
文件: lgamma.cpp 项目: chenbk85/QOR
    //------------------------------------------------------------------------------
    float Cmath::__ieee754_lgammaf_r( float x, int* signgamp )
    {
        static const float half = 5.0000000000e-01; // 0x3f000000
        static const float one =  1.0000000000e+00; // 0x3f800000
        static const float pi  =  3.1415927410e+00; // 0x40490fdb
        static const float a0  =  7.7215664089e-02; // 0x3d9e233f
        static const float a1  =  3.2246702909e-01; // 0x3ea51a66
        static const float a2  =  6.7352302372e-02; // 0x3d89f001
        static const float a3  =  2.0580807701e-02; // 0x3ca89915
        static const float a4  =  7.3855509982e-03; // 0x3bf2027e
        static const float a5  =  2.8905137442e-03; // 0x3b3d6ec6
        static const float a6  =  1.1927076848e-03; // 0x3a9c54a1
        static const float a7  =  5.1006977446e-04; // 0x3a05b634
        static const float a8  =  2.2086278477e-04; // 0x39679767
        static const float a9  =  1.0801156895e-04; // 0x38e28445
        static const float a10 =  2.5214456400e-05; // 0x37d383a2
        static const float a11 =  4.4864096708e-05; // 0x383c2c75
        static const float tc  =  1.4616321325e+00; // 0x3fbb16c3
        static const float tf  = -1.2148628384e-01; // 0xbdf8cdcd
        // tt = -(tail of tf)
        static const float tt  =  6.6971006518e-09; // 0x31e61c52
        static const float t0  =  4.8383611441e-01; // 0x3ef7b95e
        static const float t1  = -1.4758771658e-01; // 0xbe17213c
        static const float t2  =  6.4624942839e-02; // 0x3d845a15
        static const float t3  = -3.2788541168e-02; // 0xbd064d47
        static const float t4  =  1.7970675603e-02; // 0x3c93373d
        static const float t5  = -1.0314224288e-02; // 0xbc28fcfe
        static const float t6  =  6.1005386524e-03; // 0x3bc7e707
        static const float t7  = -3.6845202558e-03; // 0xbb7177fe
        static const float t8  =  2.2596477065e-03; // 0x3b141699
        static const float t9  = -1.4034647029e-03; // 0xbab7f476
        static const float t10 =  8.8108185446e-04; // 0x3a66f867
        static const float t11 = -5.3859531181e-04; // 0xba0d3085
        static const float t12 =  3.1563205994e-04; // 0x39a57b6b
        static const float t13 = -3.1275415677e-04; // 0xb9a3f927
        static const float t14 =  3.3552918467e-04; // 0x39afe9f7
        static const float u0  = -7.7215664089e-02; // 0xbd9e233f
        static const float u1  =  6.3282704353e-01; // 0x3f2200f4
        static const float u2  =  1.4549225569e+00; // 0x3fba3ae7
        static const float u3  =  9.7771751881e-01; // 0x3f7a4bb2
        static const float u4  =  2.2896373272e-01; // 0x3e6a7578
        static const float u5  =  1.3381091878e-02; // 0x3c5b3c5e
        static const float v1  =  2.4559779167e+00; // 0x401d2ebe
        static const float v2  =  2.1284897327e+00; // 0x4008392d
        static const float v3  =  7.6928514242e-01; // 0x3f44efdf
        static const float v4  =  1.0422264785e-01; // 0x3dd572af
        static const float v5  =  3.2170924824e-03; // 0x3b52d5db
        static const float s0  = -7.7215664089e-02; // 0xbd9e233f
        static const float s1  =  2.1498242021e-01; // 0x3e5c245a
        static const float s2  =  3.2577878237e-01; // 0x3ea6cc7a
        static const float s3  =  1.4635047317e-01; // 0x3e15dce6
        static const float s4  =  2.6642270386e-02; // 0x3cda40e4
        static const float s5  =  1.8402845599e-03; // 0x3af135b4
        static const float s6  =  3.1947532989e-05; // 0x3805ff67
        static const float r1  =  1.3920053244e+00; // 0x3fb22d3b
        static const float r2  =  7.2193557024e-01; // 0x3f38d0c5
        static const float r3  =  1.7193385959e-01; // 0x3e300f6e
        static const float r4  =  1.8645919859e-02; // 0x3c98bf54
        static const float r5  =  7.7794247773e-04; // 0x3a4beed6
        static const float r6  =  7.3266842264e-06; // 0x36f5d7bd
        static const float w0  =  4.1893854737e-01; // 0x3ed67f1d
        static const float w1  =  8.3333335817e-02; // 0x3daaaaab
        static const float w2  = -2.7777778450e-03; // 0xbb360b61
        static const float w3  =  7.9365057172e-04; // 0x3a500cfd
        static const float w4  = -5.9518753551e-04; // 0xba1c065c
        static const float w5  =  8.3633989561e-04; // 0x3a5b3dd2
        static const float w6  = -1.6309292987e-03; // 0xbad5c4e8
        static const float zero=  0.0000000000e+00;

        float t, y, z, nadj, p, p1, p2, p3, q, r, w;
        Cmp_signed__int32 i, hx, ix;

        get_float_word( hx, x );

        // purge off +-inf, NaN, +-0, and negative arguments
        *signgamp = 1;
        ix = hx & 0x7fffffff;
        if( ix >= 0x7f800000 )
        {
            return x * x;
        }

        if( ix == 0 )
        {
            return one / zero;
        }

        if( ix < 0x1c800000 )
        {
            // |x|<2**-70, return -log(|x|)
            if( hx < 0 )
            {
                *signgamp = -1;
                return -__ieee754_logf( -x );
            }
            else
            {
                return -__ieee754_logf( x );
            }
        }

        if( hx < 0 )
        {
            if( ix >= 0x4b000000 ) // |x|>=2**23, must be -integer
            {
                return one / zero;
            }
            t = sin_pif( x );
            if( t == zero )
            {
                return one / zero; // -integer
            }
            nadj = __ieee754_logf( pi / fabsf( t * x ) );
            if( t < zero )
            {
                *signgamp = -1;
            }
            x = -x;
        }

        // purge off 1 and 2
        if( ix == 0x3f800000 || ix == 0x40000000 )
        {
            r = 0;
        }// for x < 2.0
        else if( ix < 0x40000000 )
        {
            if( ix <= 0x3f666666 )
            {
                // lgamma(x) = lgamma(x+1)-log(x)
                r = -__ieee754_logf( x );
                if( ix >= 0x3f3b4a20 )
                {
                    y = one - x;
                    i = 0;
                }
                else if( ix >= 0x3e6d3308 )
                {
                    y = x - ( tc - one );
                    i = 1;
                }
                else
                {
                    y = x;
                    i=2;
                }
            }
            else
            {
                r = zero;
                if( ix >= 0x3fdda618 )
                {
                    y = (float)2.0 - x;
                    i = 0;
                } // [1.7316,2]
                else if( ix >= 0x3F9da620 )
                {
                    y = x - tc;
                    i = 1;
                } // [1.23,1.73]
                else
                {
                    y = x - one;
                    i = 2;
                }
            }

            switch( i )
            {
            case 0:
                z = y * y;
                p1 = a0 + z * ( a2 + z * ( a4 + z * ( a6 + z * ( a8 + z * a10 ) ) ) );
                p2 = z * ( a1 + z * ( a3 + z * ( a5 + z * ( a7 + z * ( a9 + z * a11 ) ) ) ) );
                p = y * p1 + p2;
                r += ( p - (float)0.5 * y );
                break;
            case 1:
                z = y * y;
                w = z * y;
                p1 = t0 + w * ( t3 + w * ( t6 + w * ( t9 + w * t12 ) ) ); // parallel comp
                p2 = t1 + w * ( t4 + w * ( t7 + w * ( t10 + w * t13 ) ) );
                p3 = t2 + w * ( t5 + w * ( t8 + w * ( t11 + w * t14 ) ) );
                p  = z * p1 -( tt - w * ( p2 + y * p3 ) );
                r += ( tf + p );
                break;
            case 2:
                p1 = y * ( u0 + y * ( u1 + y * ( u2 + y * ( u3 + y * ( u4 + y * u5 ) ) ) ) );
                p2 = one + y * ( v1 + y * ( v2 + y * ( v3 + y * ( v4 + y * v5 ) ) ) );
                r += ( -(float)0.5 * y + p1 / p2 );
            }
        }
        else if( ix <0x41000000 )
        {
            // x < 8.0
            i = (Cmp_signed__int32)x;
            t = zero;
            y = x -(float)i;
            p = y * ( s0 + y * ( s1 + y * ( s2 + y * ( s3 + y * ( s4 + y * ( s5 + y * s6 ) ) ) ) ) );
            q = one + y * ( r1 + y * ( r2 + y * ( r3 + y * ( r4 + y * ( r5 + y * r6 ) ) ) ) );
            r = half * y + p / q;
            z = one; // lgamma(1+s) = log(s) + lgamma(s)
            switch( i )
            {
                case 7: z *= ( y + (float)6.0 ); // FALLTHRU
                case 6: z *= ( y + (float)5.0 ); // FALLTHRU
                case 5: z *= ( y + (float)4.0 ); // FALLTHRU
                case 4: z *= ( y + (float)3.0 ); // FALLTHRU
                case 3: z *= ( y + (float)2.0 ); // FALLTHRU
                r += __ieee754_logf( z );
                break;
            }

            // 8.0 <= x < 2**58
        }
        else if( ix < 0x5c800000 )
        {
            t = __ieee754_logf( x );
            z = one / x;
            y = z * z;
            w = w0 + z * ( w1 + y * ( w2 + y * ( w3 + y * ( w4 + y * ( w5 + y * w6 ) ) ) ) );
            r = ( x - half ) * ( t - one ) + w;
        }
        else
        {
            // 2**58 <= x <= inf
            r = x * ( __ieee754_logf( x ) - one );
        }

        if( hx < 0 )
        {
            r = nadj - r;
        }
        return r;
    }