示例#1
0
double
__ieee754_exp10 (double arg)
{
  int32_t lx;
  double arg_high, arg_low;
  double exp_high, exp_low;

  if (!isfinite (arg))
    return __ieee754_exp (arg);
  if (arg < DBL_MIN_10_EXP - DBL_DIG - 10)
    return DBL_MIN * DBL_MIN;
  else if (arg > DBL_MAX_10_EXP + 1)
    return DBL_MAX * DBL_MAX;
  else if (fabs (arg) < 0x1p-56)
    return 1.0;

  GET_LOW_WORD (lx, arg);
  lx &= 0xf8000000;
  arg_high = arg;
  SET_LOW_WORD (arg_high, lx);
  arg_low = arg - arg_high;
  exp_high = arg_high * log10_high;
  exp_low = arg_high * log10_low + arg_low * M_LN10;
  return __ieee754_exp (exp_high) * __ieee754_exp (exp_low);
}
示例#2
0
文件: e_cosh.c 项目: AubrCool/glibc
double
__ieee754_cosh (double x)
{
  double t, w;
  int32_t ix;
  u_int32_t lx;

  /* High word of |x|. */
  GET_HIGH_WORD (ix, x);
  ix &= 0x7fffffff;

  /* |x| in [0,22] */
  if (ix < 0x40360000)
    {
      /* |x| in [0,0.5*ln2], return 1+expm1(|x|)^2/(2*exp(|x|)) */
      if (ix < 0x3fd62e43)
	{
	  if (ix < 0x3c800000)
	    return one;                                   /* cosh(tiny) = 1 */
	  t = __expm1 (fabs (x));
	  w = one + t;
	  return one + (t * t) / (w + w);
	}

      /* |x| in [0.5*ln2,22], return (exp(|x|)+1/exp(|x|)/2; */
      t = __ieee754_exp (fabs (x));
      return half * t + half / t;
    }

  /* |x| in [22, log(maxdouble)] return half*exp(|x|) */
  if (ix < 0x40862e42)
    return half * __ieee754_exp (fabs (x));

  /* |x| in [log(maxdouble), overflowthresold] */
  GET_LOW_WORD (lx, x);
  if (ix < 0x408633ce || ((ix == 0x408633ce) && (lx <= (u_int32_t) 0x8fb9f87d)))
    {
      w = __ieee754_exp (half * fabs (x));
      t = half * w;
      return t * w;
    }

  /* x is INF or NaN */
  if (ix >= 0x7ff00000)
    return x * x;

  /* |x| > overflowthresold, cosh(x) overflow */
  return huge * huge;
}
示例#3
0
double
__ieee754_gamma_r (double x, int *signgamp)
{
  /* We don't have a real gamma implementation now.  We'll use lgamma
     and the exp function.  But due to the required boundary
     conditions we must check some values separately.  */
  int32_t hx;
  u_int32_t lx;

  EXTRACT_WORDS (hx, lx, x);

  if (((hx & 0x7fffffff) | lx) == 0)
    {
      /* Return value for x == 0 is NaN with invalid exception.  */
      *signgamp = 0;
      return x / x;
    }
  if (hx < 0 && (u_int32_t) hx < 0xfff00000 && __rint (x) == x)
    {
      /* Return value for integer x < 0 is NaN with invalid exception.  */
      *signgamp = 0;
      return (x - x) / (x - x);
    }
  if ((unsigned int) hx == 0xfff00000 && lx==0)
    {
      /* x == -Inf.  According to ISO this is NaN.  */
      *signgamp = 0;
      return x - x;
    }

  /* XXX FIXME.  */
  return __ieee754_exp (__ieee754_lgamma_r (x, signgamp));
}
示例#4
0
double
__ieee754_sinh(double x)
{
	double t,h;
	int32_t ix,jx;

    /* High word of |x|. */
	GET_HIGH_WORD(jx,x);
	ix = jx&0x7fffffff;

    /* x is INF or NaN */
	if(ix>=0x7ff00000) return x+x;	

	h = 0.5;
	if (jx<0) h = -h;
    /* |x| in [0,22], return sign(x)*0.5*(E+E/(E+1))) */
	if (ix < 0x40360000) {		/* |x|<22 */
	    if (ix<0x3e300000) 		/* |x|<2**-28 */
		if(shuge+x>one) return x;/* sinh(tiny) = tiny with inexact */
	    t = expm1(fabs(x));
	    if(ix<0x3ff00000) return h*(2.0*t-t*t/(t+one));
	    return h*(t+t/(t+one));
	}

    /* |x| in [22, log(maxdouble)] return 0.5*exp(|x|) */
	if (ix < 0x40862E42)  return h*__ieee754_exp(fabs(x));

    /* |x| in [log(maxdouble), overflowthresold] */
	if (ix<=0x408633CE)
	    return h*2.0*__ldexp_exp(fabs(x), -1);

    /* |x| > overflowthresold, sinh(x) overflow */
	return x*shuge;
}
示例#5
0
文件: e_exp10f.c 项目: Xilinx/eglibc
float
__ieee754_exp10f (float arg)
{
  /* The argument to exp needs to be calculated in enough precision
     that the fractional part has as much precision as float, in
     addition to the bits in the integer part; using double ensures
     this.  */
  return __ieee754_exp (M_LN10 * arg);
}
示例#6
0
文件: math.c 项目: JamesLinus/inferno
void
Math_exp(void *fp)
{
	F_Math_exp *f;

	f = fp;

	*f->ret = __ieee754_exp(f->x);
}
示例#7
0
double __ieee754_exp10 (double arg)
{
  if (isfinite (arg) && arg < DBL_MIN_10_EXP - DBL_DIG - 10)
    return DBL_MIN * DBL_MIN;
  else
    /* This is a very stupid and inprecise implementation.  It'll get
       replaced sometime (soon?).  */
    return __ieee754_exp (M_LN10 * arg);
}
示例#8
0
double
exp(double x)   /* wrapper exp */
{
#ifdef _IEEE_LIBM
  return __ieee754_exp(x);
#else
  double z;
  z = __ieee754_exp(x);
  if(_LIB_VERSION == _IEEE_) return z;
  if(finite(x)) {
      if(x>o_threshold)
          return __kernel_standard(x,x,6); /* exp overflow */
      else if(x<u_threshold)
          return __kernel_standard(x,x,7); /* exp underflow */
  }
  return z;
#endif
}
示例#9
0
/* wrapper exp */
double
__exp (double x)
{
  double z = __ieee754_exp (x);
  if (__builtin_expect (!isfinite (z) || z == 0, 0)
      && isfinite (x) && _LIB_VERSION != _IEEE_)
    return __kernel_standard (x, x, 6 + !!signbit (x));

  return z;
}
示例#10
0
文件: e_sinh.c 项目: EPiCS/reconos_v2
        double __ieee754_sinh(double x)
{       
        double t,w,h;
        int ix,jx;
        unsigned lx;

    /* High word of |x|. */
        jx = CYG_LIBM_HI(x);
        ix = jx&0x7fffffff;

    /* x is INF or NaN */
        if(ix>=0x7ff00000) return x+x;  

        h = 0.5;
        if (jx<0) h = -h;
    /* |x| in [0,22], return sign(x)*0.5*(E+E/(E+1))) */
        if (ix < 0x40360000) {          /* |x|<22 */
            if (ix<0x3e300000)          /* |x|<2**-28 */
                if(shuge+x>one) return x;/* sinh(tiny) = tiny with inexact */
            t = expm1(fabs(x));
            if(ix<0x3ff00000) return h*(2.0*t-t*t/(t+one));
            return h*(t+t/(t+one));
        }

    /* |x| in [22, log(maxdouble)] return 0.5*exp(|x|) */
        if (ix < 0x40862E42)  return h*__ieee754_exp(fabs(x));

    /* |x| in [log(maxdouble), overflowthresold] */
        lx = CYG_LIBM_LO(x);
        if (ix<0x408633CE || ((ix==0x408633ce)&&(lx<=(unsigned)0x8fb9f87d))) {
            w = __ieee754_exp(0.5*fabs(x));
            t = h*w;
            return t*w;
        }

    /* |x| > overflowthresold, sinh(x) overflow */
        return x*shuge;
}
示例#11
0
double
__ieee754_cosh(double x)
{
	double t,w;
	int32_t ix;

    /* High word of |x|. */
	GET_HIGH_WORD(ix,x);
	ix &= 0x7fffffff;

    /* x is INF or NaN */
	if(ix>=0x7ff00000) return x*x;	

    /* |x| in [0,0.5*ln2], return 1+expm1(|x|)^2/(2*exp(|x|)) */
	if(ix<0x3fd62e43) {
	    t = expm1(fabs(x));
	    w = one+t;
	    if (ix<0x3c800000) return w;	/* cosh(tiny) = 1 */
	    return one+(t*t)/(w+w);
	}

    /* |x| in [0.5*ln2,22], return (exp(|x|)+1/exp(|x|)/2; */
	if (ix < 0x40360000) {
		t = __ieee754_exp(fabs(x));
		return half*t+half/t;
	}

    /* |x| in [22, log(maxdouble)] return half*exp(|x|) */
	if (ix < 0x40862E42)  return half*__ieee754_exp(fabs(x));

    /* |x| in [log(maxdouble), overflowthresold] */
	if (ix<=0x408633CE)
	    return __ldexp_exp(fabs(x), -1);

    /* |x| > overflowthresold, cosh(x) overflow */
	return huge*huge;
}
示例#12
0
EXPORT(sqInt) primitiveExp(void) {
    double rcvr;
    double result;

	rcvr = interpreterProxy->stackFloatValue(0);
	if (interpreterProxy->failed()) {
		return null;
	}
	result = __ieee754_exp(rcvr);
	if (isnan(result)) {
		return interpreterProxy->primitiveFail();
	}
	interpreterProxy->pop((interpreterProxy->methodArgumentCount()) + 1);
	interpreterProxy->pushFloat(result);
}
primitiveExp(void)
{
	// FloatMathPlugin>>#primitiveExp
    double rcvr;
    double result;

	rcvr = stackFloatValue(0);
	if (failed()) {
		return null;
	}
	result = __ieee754_exp(rcvr);
	if (isnan(result)) {
		return primitiveFail();
	}
	pop((methodArgumentCount()) + 1);
	pushFloat(result);
}
示例#14
0
文件: s_ccosh.c 项目: Xilinx/eglibc
__complex__ double
__ccosh (__complex__ double x)
{
  __complex__ double retval;
  int rcls = fpclassify (__real__ x);
  int icls = fpclassify (__imag__ x);

  if (__builtin_expect (rcls >= FP_ZERO, 1))
    {
      /* Real part is finite.  */
      if (__builtin_expect (icls >= FP_ZERO, 1))
	{
	  /* Imaginary part is finite.  */
	  const int t = (int) ((DBL_MAX_EXP - 1) * M_LN2);
	  double sinix, cosix;

	  if (__builtin_expect (icls != FP_SUBNORMAL, 1))
	    {
	      __sincos (__imag__ x, &sinix, &cosix);
	    }
	  else
	    {
	      sinix = __imag__ x;
	      cosix = 1.0;
	    }

	  if (fabs (__real__ x) > t)
	    {
	      double exp_t = __ieee754_exp (t);
	      double rx = fabs (__real__ x);
	      if (signbit (__real__ x))
		sinix = -sinix;
	      rx -= t;
	      sinix *= exp_t / 2.0;
	      cosix *= exp_t / 2.0;
	      if (rx > t)
		{
		  rx -= t;
		  sinix *= exp_t;
		  cosix *= exp_t;
		}
	      if (rx > t)
		{
		  /* Overflow (original real part of x > 3t).  */
		  __real__ retval = DBL_MAX * cosix;
		  __imag__ retval = DBL_MAX * sinix;
		}
	      else
		{
		  double exp_val = __ieee754_exp (rx);
		  __real__ retval = exp_val * cosix;
		  __imag__ retval = exp_val * sinix;
		}
	    }
	  else
	    {
	      __real__ retval = __ieee754_cosh (__real__ x) * cosix;
	      __imag__ retval = __ieee754_sinh (__real__ x) * sinix;
	    }

	  if (fabs (__real__ retval) < DBL_MIN)
	    {
	      volatile double force_underflow
		= __real__ retval * __real__ retval;
	      (void) force_underflow;
	    }
	  if (fabs (__imag__ retval) < DBL_MIN)
	    {
	      volatile double force_underflow
		= __imag__ retval * __imag__ retval;
	      (void) force_underflow;
	    }
	}
      else
	{
	  __imag__ retval = __real__ x == 0.0 ? 0.0 : __nan ("");
	  __real__ retval = __nan ("") + __nan ("");

	  if (icls == FP_INFINITE)
	    feraiseexcept (FE_INVALID);
	}
    }
  else if (rcls == FP_INFINITE)
    {
      /* Real part is infinite.  */
      if (__builtin_expect (icls > FP_ZERO, 1))
	{
	  /* Imaginary part is finite.  */
	  double sinix, cosix;

	  if (__builtin_expect (icls != FP_SUBNORMAL, 1))
	    {
	      __sincos (__imag__ x, &sinix, &cosix);
	    }
	  else
	    {
	      sinix = __imag__ x;
	      cosix = 1.0;
	    }

	  __real__ retval = __copysign (HUGE_VAL, cosix);
	  __imag__ retval = (__copysign (HUGE_VAL, sinix)
			     * __copysign (1.0, __real__ x));
	}
      else if (icls == FP_ZERO)
	{
	  /* Imaginary part is 0.0.  */
	  __real__ retval = HUGE_VAL;
	  __imag__ retval = __imag__ x * __copysign (1.0, __real__ x);
	}
      else
	{
	  /* The addition raises the invalid exception.  */
	  __real__ retval = HUGE_VAL;
	  __imag__ retval = __nan ("") + __nan ("");

	  if (icls == FP_INFINITE)
	    feraiseexcept (FE_INVALID);
	}
    }
  else
    {
      __real__ retval = __nan ("");
      __imag__ retval = __imag__ x == 0.0 ? __imag__ x : __nan ("");
    }

  return retval;
}
示例#15
0
__complex__ double
__ctanh (__complex__ double x)
{
  __complex__ double res;

  if (__glibc_unlikely (!isfinite (__real__ x) || !isfinite (__imag__ x)))
    {
      if (isinf (__real__ x))
	{
	  __real__ res = __copysign (1.0, __real__ x);
	  if (isfinite (__imag__ x) && fabs (__imag__ x) > 1.0)
	    {
	      double sinix, cosix;
	      __sincos (__imag__ x, &sinix, &cosix);
	      __imag__ res = __copysign (0.0, sinix * cosix);
	    }
	  else
	    __imag__ res = __copysign (0.0, __imag__ x);
	}
      else if (__imag__ x == 0.0)
	{
	  res = x;
	}
      else
	{
	  __real__ res = __nan ("");
	  __imag__ res = __nan ("");

	  if (isinf (__imag__ x))
	    feraiseexcept (FE_INVALID);
	}
    }
  else
    {
      double sinix, cosix;
      double den;
      const int t = (int) ((DBL_MAX_EXP - 1) * M_LN2 / 2);

      /* tanh(x+iy) = (sinh(2x) + i*sin(2y))/(cosh(2x) + cos(2y))
	 = (sinh(x)*cosh(x) + i*sin(y)*cos(y))/(sinh(x)^2 + cos(y)^2).  */

      if (__glibc_likely (fabs (__imag__ x) > DBL_MIN))
	{
	  __sincos (__imag__ x, &sinix, &cosix);
	}
      else
	{
	  sinix = __imag__ x;
	  cosix = 1.0;
	}

      if (fabs (__real__ x) > t)
	{
	  /* Avoid intermediate overflow when the imaginary part of
	     the result may be subnormal.  Ignoring negligible terms,
	     the real part is +/- 1, the imaginary part is
	     sin(y)*cos(y)/sinh(x)^2 = 4*sin(y)*cos(y)/exp(2x).  */
	  double exp_2t = __ieee754_exp (2 * t);

	  __real__ res = __copysign (1.0, __real__ x);
	  __imag__ res = 4 * sinix * cosix;
	  __real__ x = fabs (__real__ x);
	  __real__ x -= t;
	  __imag__ res /= exp_2t;
	  if (__real__ x > t)
	    {
	      /* Underflow (original real part of x has absolute value
		 > 2t).  */
	      __imag__ res /= exp_2t;
	    }
	  else
	    __imag__ res /= __ieee754_exp (2 * __real__ x);
	}
      else
	{
	  double sinhrx, coshrx;
	  if (fabs (__real__ x) > DBL_MIN)
	    {
	      sinhrx = __ieee754_sinh (__real__ x);
	      coshrx = __ieee754_cosh (__real__ x);
	    }
	  else
	    {
	      sinhrx = __real__ x;
	      coshrx = 1.0;
	    }

	  if (fabs (sinhrx) > fabs (cosix) * DBL_EPSILON)
	    den = sinhrx * sinhrx + cosix * cosix;
	  else
	    den = cosix * cosix;
	  __real__ res = sinhrx * coshrx / den;
	  __imag__ res = sinix * cosix / den;
	}
      math_check_force_underflow_complex (res);
    }

  return res;
}
示例#16
0
文件: s_cexp.c 项目: Xilinx/eglibc
__complex__ double
__cexp (__complex__ double x)
{
  __complex__ double retval;
  int rcls = fpclassify (__real__ x);
  int icls = fpclassify (__imag__ x);

  if (__builtin_expect (rcls >= FP_ZERO, 1))
    {
      /* Real part is finite.  */
      if (__builtin_expect (icls >= FP_ZERO, 1))
	{
	  /* Imaginary part is finite.  */
	  const int t = (int) ((DBL_MAX_EXP - 1) * M_LN2);
	  double sinix, cosix;

	  if (__builtin_expect (icls != FP_SUBNORMAL, 1))
	    {
	      __sincos (__imag__ x, &sinix, &cosix);
	    }
	  else
	    {
	      sinix = __imag__ x;
	      cosix = 1.0;
	    }

	  if (__real__ x > t)
	    {
	      double exp_t = __ieee754_exp (t);
	      __real__ x -= t;
	      sinix *= exp_t;
	      cosix *= exp_t;
	      if (__real__ x > t)
		{
		  __real__ x -= t;
		  sinix *= exp_t;
		  cosix *= exp_t;
		}
	    }
	  if (__real__ x > t)
	    {
	      /* Overflow (original real part of x > 3t).  */
	      __real__ retval = DBL_MAX * cosix;
	      __imag__ retval = DBL_MAX * sinix;
	    }
	  else
	    {
	      double exp_val = __ieee754_exp (__real__ x);
	      __real__ retval = exp_val * cosix;
	      __imag__ retval = exp_val * sinix;
	    }
	  if (fabs (__real__ retval) < DBL_MIN)
	    {
	      volatile double force_underflow
		= __real__ retval * __real__ retval;
	      (void) force_underflow;
	    }
	  if (fabs (__imag__ retval) < DBL_MIN)
	    {
	      volatile double force_underflow
		= __imag__ retval * __imag__ retval;
	      (void) force_underflow;
	    }
	}
      else
	{
	  /* If the imaginary part is +-inf or NaN and the real part
	     is not +-inf the result is NaN + iNaN.  */
	  __real__ retval = __nan ("");
	  __imag__ retval = __nan ("");

	  feraiseexcept (FE_INVALID);
	}
    }
  else if (__builtin_expect (rcls == FP_INFINITE, 1))
    {
      /* Real part is infinite.  */
      if (__builtin_expect (icls >= FP_ZERO, 1))
	{
	  /* Imaginary part is finite.  */
	  double value = signbit (__real__ x) ? 0.0 : HUGE_VAL;

	  if (icls == FP_ZERO)
	    {
	      /* Imaginary part is 0.0.  */
	      __real__ retval = value;
	      __imag__ retval = __imag__ x;
	    }
	  else
	    {
	      double sinix, cosix;

	      if (__builtin_expect (icls != FP_SUBNORMAL, 1))
		{
		  __sincos (__imag__ x, &sinix, &cosix);
		}
	      else
		{
		  sinix = __imag__ x;
		  cosix = 1.0;
		}

	      __real__ retval = __copysign (value, cosix);
	      __imag__ retval = __copysign (value, sinix);
	    }
	}
      else if (signbit (__real__ x) == 0)
	{
	  __real__ retval = HUGE_VAL;
	  __imag__ retval = __nan ("");

	  if (icls == FP_INFINITE)
	    feraiseexcept (FE_INVALID);
	}
      else
	{
	  __real__ retval = 0.0;
	  __imag__ retval = __copysign (0.0, __imag__ x);
	}
    }
  else
    {
      /* If the real part is NaN the result is NaN + iNaN.  */
      __real__ retval = __nan ("");
      __imag__ retval = __nan ("");

      if (rcls != FP_NAN || icls != FP_NAN)
	feraiseexcept (FE_INVALID);
    }

  return retval;
}
示例#17
0
Err mathlib_exp(UInt16 refnum, double x, double *result) {
#pragma unused(refnum)
	*result = __ieee754_exp(x);
	return mlErrNone;
}
示例#18
0
static double
gamma_positive (double x, int *exp2_adj)
{
  int local_signgam;
  if (x < 0.5)
    {
      *exp2_adj = 0;
      return __ieee754_exp (__ieee754_lgamma_r (x + 1, &local_signgam)) / x;
    }
  else if (x <= 1.5)
    {
      *exp2_adj = 0;
      return __ieee754_exp (__ieee754_lgamma_r (x, &local_signgam));
    }
  else if (x < 6.5)
    {
      /* Adjust into the range for using exp (lgamma).  */
      *exp2_adj = 0;
      double n = __ceil (x - 1.5);
      double x_adj = x - n;
      double eps;
      double prod = __gamma_product (x_adj, 0, n, &eps);
      return (__ieee754_exp (__ieee754_lgamma_r (x_adj, &local_signgam))
	      * prod * (1.0 + eps));
    }
  else
    {
      double eps = 0;
      double x_eps = 0;
      double x_adj = x;
      double prod = 1;
      if (x < 12.0)
	{
	  /* Adjust into the range for applying Stirling's
	     approximation.  */
	  double n = __ceil (12.0 - x);
#if FLT_EVAL_METHOD != 0
	  volatile
#endif
	  double x_tmp = x + n;
	  x_adj = x_tmp;
	  x_eps = (x - (x_adj - n));
	  prod = __gamma_product (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.  */
      double exp_adj = -eps;
      double x_adj_int = __round (x_adj);
      double x_adj_frac = x_adj - x_adj_int;
      int x_adj_log2;
      double x_adj_mant = __frexp (x_adj, &x_adj_log2);
      if (x_adj_mant < M_SQRT1_2)
	{
	  x_adj_log2--;
	  x_adj_mant *= 2.0;
	}
      *exp2_adj = x_adj_log2 * (int) x_adj_int;
      double ret = (__ieee754_pow (x_adj_mant, x_adj)
		    * __ieee754_exp2 (x_adj_log2 * x_adj_frac)
		    * __ieee754_exp (-x_adj)
		    * __ieee754_sqrt (2 * M_PI / x_adj)
		    / prod);
      exp_adj += x_eps * __ieee754_log (x);
      double bsum = gamma_coeff[NCOEFF - 1];
      double 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 * __expm1 (exp_adj);
    }
}
示例#19
0
文件: s_cexp.c 项目: dreal/tai
__complex__ double
__cexp (__complex__ double x)
{
  __complex__ double retval;
  int rcls = fpclassify (__real__ x);
  int icls = fpclassify (__imag__ x);

  if (__builtin_expect (rcls >= FP_ZERO, 1))
    {
      /* Real part is finite.  */
      if (__builtin_expect (icls >= FP_ZERO, 1))
	{
	  /* Imaginary part is finite.  */
	  double exp_val = __ieee754_exp (__real__ x);
	  double sinix, cosix;

	  __sincos (__imag__ x, &sinix, &cosix);

	  if (isfinite (exp_val))
	    {
	      __real__ retval = exp_val * cosix;
	      __imag__ retval = exp_val * sinix;
	    }
	  else
	    {
	      __real__ retval = __copysign (exp_val, cosix);
	      __imag__ retval = __copysign (exp_val, sinix);
	    }
	}
      else
	{
	  /* If the imaginary part is +-inf or NaN and the real part
	     is not +-inf the result is NaN + iNaN.  */
	  __real__ retval = __nan ("");
	  __imag__ retval = __nan ("");

	  feraiseexcept (FE_INVALID);
	}
    }
  else if (__builtin_expect (rcls == FP_INFINITE, 1))
    {
      /* Real part is infinite.  */
      if (__builtin_expect (icls >= FP_ZERO, 1))
	{
	  /* Imaginary part is finite.  */
	  double value = signbit (__real__ x) ? 0.0 : HUGE_VAL;

	  if (icls == FP_ZERO)
	    {
	      /* Imaginary part is 0.0.  */
	      __real__ retval = value;
	      __imag__ retval = __imag__ x;
	    }
	  else
	    {
	      double sinix, cosix;

	      __sincos (__imag__ x, &sinix, &cosix);

	      __real__ retval = __copysign (value, cosix);
	      __imag__ retval = __copysign (value, sinix);
	    }
	}
      else if (signbit (__real__ x) == 0)
	{
	  __real__ retval = HUGE_VAL;
	  __imag__ retval = __nan ("");

	  if (icls == FP_INFINITE)
	    feraiseexcept (FE_INVALID);
	}
      else
	{
	  __real__ retval = 0.0;
	  __imag__ retval = __copysign (0.0, __imag__ x);
	}
    }
  else
    {
      /* If the real part is NaN the result is NaN + iNaN.  */
      __real__ retval = __nan ("");
      __imag__ retval = __nan ("");

      if (rcls != FP_NAN || icls != FP_NAN)
	feraiseexcept (FE_INVALID);
    }

  return retval;
}
示例#20
0
文件: s_csin.c 项目: AubrCool/glibc
__complex__ double
__csin (__complex__ double x)
{
  __complex__ double retval;
  int negate = signbit (__real__ x);
  int rcls = fpclassify (__real__ x);
  int icls = fpclassify (__imag__ x);

  __real__ x = fabs (__real__ x);

  if (__glibc_likely (icls >= FP_ZERO))
    {
      /* Imaginary part is finite.  */
      if (__glibc_likely (rcls >= FP_ZERO))
	{
	  /* Real part is finite.  */
	  const int t = (int) ((DBL_MAX_EXP - 1) * M_LN2);
	  double sinix, cosix;

	  if (__glibc_likely (rcls != FP_SUBNORMAL))
	    {
	      __sincos (__real__ x, &sinix, &cosix);
	    }
	  else
	    {
	      sinix = __real__ x;
	      cosix = 1.0;
	    }

	  if (fabs (__imag__ x) > t)
	    {
	      double exp_t = __ieee754_exp (t);
	      double ix = fabs (__imag__ x);
	      if (signbit (__imag__ x))
		cosix = -cosix;
	      ix -= t;
	      sinix *= exp_t / 2.0;
	      cosix *= exp_t / 2.0;
	      if (ix > t)
		{
		  ix -= t;
		  sinix *= exp_t;
		  cosix *= exp_t;
		}
	      if (ix > t)
		{
		  /* Overflow (original imaginary part of x > 3t).  */
		  __real__ retval = DBL_MAX * sinix;
		  __imag__ retval = DBL_MAX * cosix;
		}
	      else
		{
		  double exp_val = __ieee754_exp (ix);
		  __real__ retval = exp_val * sinix;
		  __imag__ retval = exp_val * cosix;
		}
	    }
	  else
	    {
	      __real__ retval = __ieee754_cosh (__imag__ x) * sinix;
	      __imag__ retval = __ieee754_sinh (__imag__ x) * cosix;
	    }

	  if (negate)
	    __real__ retval = -__real__ retval;

	  if (fabs (__real__ retval) < DBL_MIN)
	    {
	      volatile double force_underflow
		= __real__ retval * __real__ retval;
	      (void) force_underflow;
	    }
	  if (fabs (__imag__ retval) < DBL_MIN)
	    {
	      volatile double force_underflow
		= __imag__ retval * __imag__ retval;
	      (void) force_underflow;
	    }
	}
      else
	{
	  if (icls == FP_ZERO)
	    {
	      /* Imaginary part is 0.0.  */
	      __real__ retval = __nan ("");
	      __imag__ retval = __imag__ x;

	      if (rcls == FP_INFINITE)
		feraiseexcept (FE_INVALID);
	    }
	  else
	    {
	      __real__ retval = __nan ("");
	      __imag__ retval = __nan ("");

	      feraiseexcept (FE_INVALID);
	    }
	}
    }
  else if (icls == FP_INFINITE)
    {
      /* Imaginary part is infinite.  */
      if (rcls == FP_ZERO)
	{
	  /* Real part is 0.0.  */
	  __real__ retval = __copysign (0.0, negate ? -1.0 : 1.0);
	  __imag__ retval = __imag__ x;
	}
      else if (rcls > FP_ZERO)
	{
	  /* Real part is finite.  */
	  double sinix, cosix;

	  if (__glibc_likely (rcls != FP_SUBNORMAL))
	    {
	      __sincos (__real__ x, &sinix, &cosix);
	    }
	  else
	    {
	      sinix = __real__ x;
	      cosix = 1.0;
	    }

	  __real__ retval = __copysign (HUGE_VAL, sinix);
	  __imag__ retval = __copysign (HUGE_VAL, cosix);

	  if (negate)
	    __real__ retval = -__real__ retval;
	  if (signbit (__imag__ x))
	    __imag__ retval = -__imag__ retval;
	}
      else
	{
	  /* The addition raises the invalid exception.  */
	  __real__ retval = __nan ("");
	  __imag__ retval = HUGE_VAL;

	  if (rcls == FP_INFINITE)
	    feraiseexcept (FE_INVALID);
	}
    }
  else
    {
      if (rcls == FP_ZERO)
	__real__ retval = __copysign (0.0, negate ? -1.0 : 1.0);
      else
	__real__ retval = __nan ("");
      __imag__ retval = __nan ("");
    }

  return retval;
}