コード例 #1
0
float FN_PROTOTYPE(exp2f)(float x)
{
  static const float
    max_exp2_arg = 128.0F,  /* 0x43000000 */
    min_exp2_arg = -149.0F, /* 0xc3150000 */
    log2 = 6.931471824645996e-01F, /* 0x3f317218 */
    one_by_32_lead = 0.03125F;

  float y, z1, z2, z;
  int m;
  unsigned int ux, ax;

  /*
    Computation of exp2f(x).

    We compute the values m, z1, and z2 such that
    exp2f(x) = 2**m * (z1 + z2),  where exp2f(x) is 2**x.

    Computations needed in order to obtain m, z1, and z2
    involve three steps.

    First, we reduce the argument x to the form
    x = n/32 + remainder,
    where n has the value of an integer and |remainder| <= 1/64.
    The value of n = x * 32 rounded to the nearest integer and
    the remainder = x - n/32.

    Second, we approximate exp2f(r1 + r2) - 1 where r1 is the leading
    part of the remainder and r2 is the trailing part of the remainder.

    Third, we reconstruct exp2f(x) so that
    exp2f(x) = 2**m * (z1 + z2).
  */

  GET_BITS_SP32(x, ux);
  ax = ux & (~SIGNBIT_SP32);

  if (ax >= 0x43000000) /* abs(x) >= 128.0 */
    {
      if(ax >= 0x7f800000)
        {
          /* x is either NaN or infinity */
          if (ux & MANTBITS_SP32)
            /* x is NaN */
            return x + x; /* Raise invalid if it is a signalling NaN */
          else if (ux & SIGNBIT_SP32)
            /* x is negative infinity; return 0.0 with no flags. */
            return 0.0F;
          else
            /* x is positive infinity */
            return x;
        }
      if (x > max_exp2_arg)
        /* Return +infinity with overflow flag */
        return retval_errno_erange_overflow(x);
      else if (x < min_exp2_arg)
        /* x is negative. Return +zero with underflow and inexact flags */
        return retval_errno_erange_underflow(x);
    }

  /* Handle small arguments separately */
  if (ax < 0x3cb8aa3b)   /* abs(x) < 1/(64*log2) */
    {
      if (ax < 0x32800000)   /* abs(x) < 2^(-26) */
        return 1.0F + x; /* Raises inexact if x is non-zero */
      else
        {
	  y = log2*x;
      z = ((((((((
		    1.0F/40320)*y+
		   1.0F/5040)*y+
		  1.0F/720)*y+
		 1.0F/120)*y+
		1.0F/24)*y+
	       1.0F/6)*y+
	      1.0F/2)*y+
               1.0F)*y + 1.0F;
        }
    }
  else
    {
      /* Find m, z1 and z2 such that exp2f(x) = 2**m * (z1 + z2) */

      splitexpf(x, log2, 32.0F, one_by_32_lead, 0.0F, &m, &z1, &z2);

      /* Scale (z1 + z2) by 2.0**m */

      if (m >= EMIN_SP32 && m <= EMAX_SP32)
        z = scaleFloat_1((float)(z1+z2),m);
      else
        z = scaleFloat_2((float)(z1+z2),m);
    }
  return z;
}
コード例 #2
0
ファイル: w_expf.c プロジェクト: manojxantony/compiler
float FN_PROTOTYPE(expf)(float x)
{
  static const float
       max_exp_arg =  8.8722839355E+01F, /* 0x42B17218 */
       min_exp_arg = -1.0327893066E+02F, /* 0xC2CE8ED0 */
 thirtytwo_by_log2 =  4.6166240692E+01F, /* 0x4238AA3B */
   log2_by_32_lead =  2.1659851074E-02F, /* 0x3CB17000 */
   log2_by_32_tail =  9.9831822808E-07F; /* 0x3585FDF4 */

  float z1, z2, z;
  int m;
  unsigned int ux, ax;

  /*
    Computation of exp(x).

    We compute the values m, z1, and z2 such that
    exp(x) = 2**m * (z1 + z2),  where
    exp(x) is the natural exponential of x.

    Computations needed in order to obtain m, z1, and z2
    involve three steps.

    First, we reduce the argument x to the form
    x = n * log2/32 + remainder,
    where n has the value of an integer and |remainder| <= log2/64.
    The value of n = x * 32/log2 rounded to the nearest integer and
    the remainder = x - n*log2/32.

    Second, we approximate exp(r1 + r2) - 1 where r1 is the leading
    part of the remainder and r2 is the trailing part of the remainder.

    Third, we reconstruct the exponential of x so that
    exp(x) = 2**m * (z1 + z2).
  */

  GET_BITS_SP32(x, ux);
  ax = ux & (~SIGNBIT_SP32);

  if (ax >= 0x42B17218) /* abs(x) >= 88.7... */
    {
      if(ax >= 0x7f800000)
        {
          /* x is either NaN or infinity */
          if (ux & MANTBITS_SP32)
            /* x is NaN */
            return x + x; /* Raise invalid if it is a signalling NaN */
          else if (ux & SIGNBIT_SP32)
            /* x is negative infinity; return 0.0 with no flags */
            return 0.0;
          else
            /* x is positive infinity */
            return x;
        }
      if (x > max_exp_arg)
        /* Return +infinity with overflow flag */
        return retval_errno_erange_overflow(x);
      else if (x < min_exp_arg)
        /* x is negative. Return +zero with underflow and inexact flags */
        return retval_errno_erange_underflow(x);
    }

  /* Handle small arguments separately */
  if (ax < 0x3c800000)   /* abs(x) < 1/64 */
    {
      if (ax < 0x32800000)   /* abs(x) < 2^(-26) */
        return 1.0F + x; /* Raises inexact if x is non-zero */
      else
        z = (((((((
                   1.0F/5040)*x+
                  1.0F/720)*x+
                 1.0F/120)*x+
                1.0F/24)*x+
               1.0F/6)*x+
              1.0F/2)*x+
             1.0F)*x + 1.0F;
    }
  else
    {
      /* Find m and z such that exp(x) = 2**m * (z1 + z2) */

      splitexpf(x, 1.0F, thirtytwo_by_log2, log2_by_32_lead,
                log2_by_32_tail, &m, &z1, &z2);

      /* Scale (z1 + z2) by 2.0**m */

      if (m >= EMIN_SP32 && m <= EMAX_SP32)
        z = scaleFloat_1((float)(z1+z2),m);
      else
        z = scaleFloat_2((float)(z1+z2),m);
    }
  return z;
}
コード例 #3
0
float FN_PROTOTYPE(exp10f)(float x)
{
  static const float
         max_exp10_arg = 3.8531841278E+01F, /* 0x421A209B */
         min_exp10_arg =-4.4853469848E+01F, /* 0xC23369F4 */
                 log10 = 2.3025850929E+00F, /* 0x40135D8E */
 thirtytwo_by_log10of2 = 1.0630169677E+02F, /* 0x42D49A78 */
   log10of2_by_32_lead = 9.4070434570E-03F, /* 0x3C1A2000 */
   log10of2_by_32_tail = 1.4390730030E-07F; /* 0x341A84F0 */

  float y, z1, z2, z;
  int m;
  unsigned int ux, ax;

  /*
    Computation of exp10f (x).

    We compute the values m, z1, and z2 such that
    exp10f(x) = 2**m * (z1 + z2),  where exp10f(x) is 10**x.

    Computations needed in order to obtain m, z1, and z2
    involve three steps.

    First, we reduce the argument x to the form
    x = n * log10of2/32 + remainder,
    where n has the value of an integer and |remainder| <= log10of2/64.
    The value of n = x * 32/log10of2 rounded to the nearest integer and
    the remainder = x - n*log10of2/32.

    Second, we approximate exp10f(r1 + r2) - 1 where r1 is the leading
    part of the remainder and r2 is the trailing part of the remainder.

    Third, we reconstruct exp10f(x) so that
    exp10f(x) = 2**m * (z1 + z2).
  */

  GET_BITS_SP32(x, ux);
  ax = ux & (~SIGNBIT_SP32);

  if (ax >= 0x421A209B) /* abs(x) >= 38.5... */
    {
      if(ax >= 0x7f800000)
        {
          /* x is either NaN or infinity */
          if (ux & MANTBITS_SP32)
            /* x is NaN */
            return x + x; /* Raise invalid if it is a signalling NaN */
          else if (ux & SIGNBIT_SP32)
            /* x is negative infinity; return 0.0 with no flags. */
            return 0.0F;
          else
            /* x is positive infinity */
            return x;
        }
      if (x > max_exp10_arg)
        /* Return +infinity with overflow flag */
        return retval_errno_erange_overflow(x);
      else if (x < min_exp10_arg)
        /* x is negative. Return +zero with underflow and inexact flags */
        return retval_errno_erange_underflow(x);
    }

  /* Handle small arguments separately */
  if (ax < 0x3bde5bd9)   /* abs(x) < 1/(64*log10) */
    {
      if (ax < 0x32800000)   /* abs(x) < 2^(-26) */
        return 1.0F + x; /* Raises inexact if x is non-zero */
      else
        {
        y = log10*x;
      z = ((((((((
		    1.0F/40320)*x+
		   1.0F/5040)*y+
		  1.0F/720)*y+
		 1.0F/120)*y+
		1.0F/24)*y+
	       1.0F/6)*y+
	      1.0F/2)*y+
               1.0F)*y + 1.0F;
        }
    }
  else
    {
      /* Find m, z1 and z2 such that exp10f(x) = 2**m * (z1 + z2) */

      splitexpf(x, log10, thirtytwo_by_log10of2, log10of2_by_32_lead,
                log10of2_by_32_tail, &m, &z1, &z2);

      /* Scale (z1 + z2) by 2.0**m */

      if (m >= EMIN_SP32 && m <= EMAX_SP32)
        z = scaleFloat_1((float)(z1+z2),m);
      else
        z = scaleFloat_2((float)(z1+z2),m);
    }
  return z;
}