示例#1
0
文件: w_exp2.c 项目: AdvancedC/glibc
double
__exp2 (double x)
{
  double z = __ieee754_exp2 (x);
  if (__builtin_expect (!__finite (z), 0)
      && __finite (x) && _LIB_VERSION != _IEEE_)
    /* exp2 overflow: 44, exp2 underflow: 45 */
    return __kernel_standard (x, x, 44 + !!__signbit (x));

  return z;
}
示例#2
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);
    }
}