コード例 #1
0
ファイル: e_expf.c プロジェクト: KubaKaszycki/kklibc
float
__ieee754_expf (float x)
{
  static const float himark = 88.72283935546875;
  static const float lomark = -103.972084045410;
  /* Check for usual case.  */
  if (isless (x, himark) && isgreater (x, lomark))
    {
      static const float THREEp42 = 13194139533312.0;
      static const float THREEp22 = 12582912.0;
      /* 1/ln(2).  */
#undef M_1_LN2
      static const float M_1_LN2 = 1.44269502163f;
      /* ln(2) */
#undef M_LN2
      static const double M_LN2 = .6931471805599452862;

      int tval;
      double x22, t, result, dx;
      float n, delta;
      union ieee754_double ex2_u;

      {
	SET_RESTORE_ROUND_NOEXF (FE_TONEAREST);

	/* Calculate n.  */
	n = x * M_1_LN2 + THREEp22;
	n -= THREEp22;
	dx = x - n*M_LN2;

	/* Calculate t/512.  */
	t = dx + THREEp42;
	t -= THREEp42;
	dx -= t;

	/* Compute tval = t.  */
	tval = (int) (t * 512.0);

	if (t >= 0)
	  delta = - __exp_deltatable[tval];
	else
	  delta = __exp_deltatable[-tval];

	/* Compute ex2 = 2^n e^(t/512+delta[t]).  */
	ex2_u.d = __exp_atable[tval+177];
	ex2_u.ieee.exponent += (int) n;

	/* Approximate e^(dx+delta) - 1, using a second-degree polynomial,
	   with maximum error in [-2^-10-2^-28,2^-10+2^-28]
	   less than 5e-11.  */
	x22 = (0.5000000496709180453 * dx + 1.0000001192102037084) * dx + delta;
      }

      /* Return result.  */
      result = x22 * ex2_u.d + ex2_u.d;
      return (float) result;
    }
  /* Exceptional cases:  */
  else if (isless (x, himark))
    {
      if (isinf (x))
	/* e^-inf == 0, with no error.  */
	return 0;
      else
	/* Underflow */
	return TWOM100 * TWOM100;
    }
  else
    /* Return x, if x is a NaN or Inf; or overflow, otherwise.  */
    return TWO127*x;
}
コード例 #2
0
ファイル: e_exp2f.c プロジェクト: siddhesh/glibc
float
__ieee754_exp2f (float x)
{
  static const float himark = (float) FLT_MAX_EXP;
  static const float lomark = (float) (FLT_MIN_EXP - FLT_MANT_DIG - 1);

  /* Check for usual case.  */
  if (isless (x, himark) && isgreaterequal (x, lomark))
    {
      static const float THREEp14 = 49152.0;
      int tval, unsafe;
      float rx, x22, result;
      union ieee754_float ex2_u, scale_u;

      if (fabsf (x) < FLT_EPSILON / 4.0f)
	return 1.0f + x;

      {
	SET_RESTORE_ROUND_NOEXF (FE_TONEAREST);

	/* 1. Argument reduction.
	   Choose integers ex, -128 <= t < 128, and some real
	   -1/512 <= x1 <= 1/512 so that
	   x = ex + t/512 + x1.

	   First, calculate rx = ex + t/256.  */
	rx = x + THREEp14;
	rx -= THREEp14;
	x -= rx;  /* Compute x=x1. */
	/* Compute tval = (ex*256 + t)+128.
	   Now, t = (tval mod 256)-128 and ex=tval/256  [that's mod, NOT %;
	   and /-round-to-nearest not the usual c integer /].  */
	tval = (int) (rx * 256.0f + 128.0f);

	/* 2. Adjust for accurate table entry.
	   Find e so that
	   x = ex + t/256 + e + x2
	   where -7e-4 < e < 7e-4, and
	   (float)(2^(t/256+e))
	   is accurate to one part in 2^-64.  */

	/* 'tval & 255' is the same as 'tval%256' except that it's always
	   positive.
	   Compute x = x2.  */
	x -= __exp2f_deltatable[tval & 255];

	/* 3. Compute ex2 = 2^(t/255+e+ex).  */
	ex2_u.f = __exp2f_atable[tval & 255];
	tval >>= 8;
	/* x2 is an integer multiple of 2^-30; avoid intermediate
	   underflow from the calculation of x22 * x.  */
	unsafe = abs(tval) >= -FLT_MIN_EXP - 32;
	ex2_u.ieee.exponent += tval >> unsafe;
	scale_u.f = 1.0;
	scale_u.ieee.exponent += tval - (tval >> unsafe);

	/* 4. Approximate 2^x2 - 1, using a second-degree polynomial,
	   with maximum error in [-2^-9 - 2^-14, 2^-9 + 2^-14]
	   less than 1.3e-10.  */

	x22 = (.24022656679f * x + .69314736128f) * ex2_u.f;
      }

      /* 5. Return (2^x2-1) * 2^(t/512+e+ex) + 2^(t/512+e+ex).  */
      result = x22 * x + ex2_u.f;

      if (!unsafe)
	return result;
      else
	{
	  result *= scale_u.f;
	  math_check_force_underflow_nonneg (result);
	  return result;
	}
    }
  /* Exceptional cases:  */
  else if (isless (x, himark))