Back to index

glibc  2.9
Defines | Functions | Variables
e_exp2f.c File Reference
#include <stdlib.h>
#include <float.h>
#include <ieee754.h>
#include <math.h>
#include <fenv.h>
#include <inttypes.h>
#include <math_private.h>
#include "t_exp2f.h"

Go to the source code of this file.

Defines

#define _GNU_SOURCE

Functions

float __ieee754_exp2f (float x)

Variables

static const volatile float TWOM100 = 7.88860905e-31
static const volatile float TWO127 = 1.7014118346e+38

Define Documentation

#define _GNU_SOURCE

Definition at line 29 of file e_exp2f.c.


Function Documentation

float __ieee754_exp2f ( float  x)

Definition at line 45 of file e_exp2f.c.

{
  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;
      fenv_t oldenv;

      feholdexcept (&oldenv);
#ifdef FE_TONEAREST
      /* If we don't have this, it's too bad.  */
      fesetround (FE_TONEAREST);
#endif

      /* 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;
      unsafe = abs(tval) >= -FLT_MIN_EXP - 1;
      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).  */
      fesetenv (&oldenv);

      result = x22 * x + ex2_u.f;

      if (!unsafe)
       return result;
      else
       return result * scale_u.f;
    }
  /* Exceptional cases:  */
  else if (isless (x, himark))
    {
      if (__isinff (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;
}

Here is the call graph for this function:

Here is the caller graph for this function:


Variable Documentation

const volatile float TWO127 = 1.7014118346e+38 [static]

Definition at line 42 of file e_exp2f.c.

const volatile float TWOM100 = 7.88860905e-31 [static]

Definition at line 41 of file e_exp2f.c.