/* @(#)s_expm1.c 5.1 93/09/24 */
/*
 * ====================================================
 * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
 *
 * Developed at SunPro, a Sun Microsystems, Inc. business.
 * Permission to use, copy, modify, and distribute this
 * software is freely granted, provided that this notice
 * is preserved.
 * ====================================================
 */
/* Modified by Naohiko Shimizu/Tokai University, Japan 1997/08/25,
   for performance improvement on pipelined processors.
 */

/* expm1(x)
 * Returns exp(x)-1, the exponential of x minus 1.
 *
 * Method
 *   1. Argument reduction:
 *	Given x, find r and integer k such that
 *
 *               x = k*ln2 + r,  |r| <= 0.5*ln2 ~ 0.34658
 *
 *      Here a correction term c will be computed to compensate
 *	the error in r when rounded to a floating-point number.
 *
 *   2. Approximating expm1(r) by a special rational function on
 *	the interval [0,0.34658]:
 *	Since
 *	    r*(exp(r)+1)/(exp(r)-1) = 2+ r^2/6 - r^4/360 + ...
 *	we define R1(r*r) by
 *	    r*(exp(r)+1)/(exp(r)-1) = 2+ r^2/6 * R1(r*r)
 *	That is,
 *	    R1(r**2) = 6/r *((exp(r)+1)/(exp(r)-1) - 2/r)
 *		     = 6/r * ( 1 + 2.0*(1/(exp(r)-1) - 1/r))
 *		     = 1 - r^2/60 + r^4/2520 - r^6/100800 + ...
 *      We use a special Reme algorithm on [0,0.347] to generate
 *	a polynomial of degree 5 in r*r to approximate R1. The
 *	maximum error of this polynomial approximation is bounded
 *	by 2**-61. In other words,
 *	    R1(z) ~ 1.0 + Q1*z + Q2*z**2 + Q3*z**3 + Q4*z**4 + Q5*z**5
 *	where	Q1  =  -1.6666666666666567384E-2,
 *		Q2  =   3.9682539681370365873E-4,
 *		Q3  =  -9.9206344733435987357E-6,
 *		Q4  =   2.5051361420808517002E-7,
 *		Q5  =  -6.2843505682382617102E-9;
 *	(where z=r*r, and the values of Q1 to Q5 are listed below)
 *	with error bounded by
 *	    |                  5           |     -61
 *	    | 1.0+Q1*z+...+Q5*z   -  R1(z) | <= 2
 *	    |                              |
 *
 *	expm1(r) = exp(r)-1 is then computed by the following
 *	specific way which minimize the accumulation rounding error:
 *			       2     3
 *			      r     r    [ 3 - (R1 + R1*r/2)  ]
 *	      expm1(r) = r + --- + --- * [--------------------]
 *			      2     2    [ 6 - r*(3 - R1*r/2) ]
 *
 *	To compensate the error in the argument reduction, we use
 *		expm1(r+c) = expm1(r) + c + expm1(r)*c
 *			   ~ expm1(r) + c + r*c
 *	Thus c+r*c will be added in as the correction terms for
 *	expm1(r+c). Now rearrange the term to avoid optimization
 *	screw up:
 *			(      2                                    2 )
 *			({  ( r    [ R1 -  (3 - R1*r/2) ]  )  }    r  )
 *	 expm1(r+c)~r - ({r*(--- * [--------------------]-c)-c} - --- )
 *			({  ( 2    [ 6 - r*(3 - R1*r/2) ]  )  }    2  )
 *                      (                                             )
 *
 *		   = r - E
 *   3. Scale back to obtain expm1(x):
 *	From step 1, we have
 *	   expm1(x) = either 2^k*[expm1(r)+1] - 1
 *		    = or     2^k*[expm1(r) + (1-2^-k)]
 *   4. Implementation notes:
 *	(A). To save one multiplication, we scale the coefficient Qi
 *	     to Qi*2^i, and replace z by (x^2)/2.
 *	(B). To achieve maximum accuracy, we compute expm1(x) by
 *	  (i)   if x < -56*ln2, return -1.0, (raise inexact if x!=inf)
 *	  (ii)  if k=0, return r-E
 *	  (iii) if k=-1, return 0.5*(r-E)-0.5
 *        (iv)	if k=1 if r < -0.25, return 2*((r+0.5)- E)
 *		       else	     return  1.0+2.0*(r-E);
 *	  (v)   if (k<-2||k>56) return 2^k(1-(E-r)) - 1 (or exp(x)-1)
 *	  (vi)  if k <= 20, return 2^k((1-2^-k)-(E-r)), else
 *	  (vii) return 2^k(1-((E+2^-k)-r))
 *
 * Special cases:
 *	expm1(INF) is INF, expm1(NaN) is NaN;
 *	expm1(-INF) is -1, and
 *	for finite argument, only expm1(0)=0 is exact.
 *
 * Accuracy:
 *	according to an error analysis, the error is always less than
 *	1 ulp (unit in the last place).
 *
 * Misc. info.
 *	For IEEE double
 *	    if x >  7.09782712893383973096e+02 then expm1(x) overflow
 *
 * Constants:
 * The hexadecimal values are the intended ones for the following
 * constants. The decimal values may be used, provided that the
 * compiler will convert from decimal to binary accurately enough
 * to produce the hexadecimal values shown.
 */

#include <errno.h>
#include <math.h>
#include <math_private.h>
#define one Q[0]
static const double
  huge = 1.0e+300,
  tiny = 1.0e-300,
  o_threshold = 7.09782712893383973096e+02,  /* 0x40862E42, 0xFEFA39EF */
  ln2_hi = 6.93147180369123816490e-01,       /* 0x3fe62e42, 0xfee00000 */
  ln2_lo = 1.90821492927058770002e-10,       /* 0x3dea39ef, 0x35793c76 */
  invln2 = 1.44269504088896338700e+00,       /* 0x3ff71547, 0x652b82fe */
/* scaled coefficients related to expm1 */
  Q[] = { 1.0, -3.33333333333331316428e-02, /* BFA11111 111110F4 */
	  1.58730158725481460165e-03, /* 3F5A01A0 19FE5585 */
	  -7.93650757867487942473e-05, /* BF14CE19 9EAADBB7 */
	  4.00821782732936239552e-06, /* 3ED0CFCA 86E65239 */
	  -2.01099218183624371326e-07 }; /* BE8AFDB7 6E09C32D */

double
__expm1 (double x)
{
  double y, hi, lo, c, t, e, hxs, hfx, r1, h2, h4, R1, R2, R3;
  int32_t k, xsb;
  u_int32_t hx;

  GET_HIGH_WORD (hx, x);
  xsb = hx & 0x80000000;                /* sign bit of x */
  if (xsb == 0)
    y = x;
  else
    y = -x;                             /* y = |x| */
  hx &= 0x7fffffff;                     /* high word of |x| */

  /* filter out huge and non-finite argument */
  if (hx >= 0x4043687A)                         /* if |x|>=56*ln2 */
    {
      if (hx >= 0x40862E42)                     /* if |x|>=709.78... */
	{
	  if (hx >= 0x7ff00000)
	    {
	      u_int32_t low;
	      GET_LOW_WORD (low, x);
	      if (((hx & 0xfffff) | low) != 0)
		return x + x;            /* NaN */
	      else
		return (xsb == 0) ? x : -1.0;    /* exp(+-inf)={inf,-1} */
	    }
	  if (x > o_threshold)
	    {
	      __set_errno (ERANGE);
	      return huge * huge;   /* overflow */
	    }
	}
      if (xsb != 0)      /* x < -56*ln2, return -1.0 with inexact */
	{
	  math_force_eval (x + tiny);           /* raise inexact */
	  return tiny - one;            /* return -1 */
	}
    }

  /* argument reduction */
  if (hx > 0x3fd62e42)                  /* if  |x| > 0.5 ln2 */
    {
      if (hx < 0x3FF0A2B2)              /* and |x| < 1.5 ln2 */
	{
	  if (xsb == 0)
	    {
	      hi = x - ln2_hi; lo = ln2_lo;  k = 1;
	    }
	  else
	    {
	      hi = x + ln2_hi; lo = -ln2_lo;  k = -1;
	    }
	}
      else
	{
	  k = invln2 * x + ((xsb == 0) ? 0.5 : -0.5);
	  t = k;
	  hi = x - t * ln2_hi;          /* t*ln2_hi is exact here */
	  lo = t * ln2_lo;
	}
      x = hi - lo;
      c = (hi - x) - lo;
    }
  else if (hx < 0x3c900000)             /* when |x|<2**-54, return x */
    {
      t = huge + x;     /* return x with inexact flags when x!=0 */
      return x - (t - (huge + x));
    }
  else
    k = 0;

  /* x is now in primary range */
  hfx = 0.5 * x;
  hxs = x * hfx;
  R1 = one + hxs * Q[1]; h2 = hxs * hxs;
  R2 = Q[2] + hxs * Q[3]; h4 = h2 * h2;
  R3 = Q[4] + hxs * Q[5];
  r1 = R1 + h2 * R2 + h4 * R3;
  t = 3.0 - r1 * hfx;
  e = hxs * ((r1 - t) / (6.0 - x * t));
  if (k == 0)
    return x - (x * e - hxs);                   /* c is 0 */
  else
    {
      e = (x * (e - c) - c);
      e -= hxs;
      if (k == -1)
	return 0.5 * (x - e) - 0.5;
      if (k == 1)
	{
	  if (x < -0.25)
	    return -2.0 * (e - (x + 0.5));
	  else
	    return one + 2.0 * (x - e);
	}
      if (k <= -2 || k > 56)         /* suffice to return exp(x)-1 */
	{
	  u_int32_t high;
	  y = one - (e - x);
	  GET_HIGH_WORD (high, y);
	  SET_HIGH_WORD (y, high + (k << 20));  /* add k to y's exponent */
	  return y - one;
	}
      t = one;
      if (k < 20)
	{
	  u_int32_t high;
	  SET_HIGH_WORD (t, 0x3ff00000 - (0x200000 >> k));    /* t=1-2^-k */
	  y = t - (e - x);
	  GET_HIGH_WORD (high, y);
	  SET_HIGH_WORD (y, high + (k << 20));  /* add k to y's exponent */
	}
      else
	{
	  u_int32_t high;
	  SET_HIGH_WORD (t, ((0x3ff - k) << 20));       /* 2^-k */
	  y = x - (e + t);
	  y += one;
	  GET_HIGH_WORD (high, y);
	  SET_HIGH_WORD (y, high + (k << 20));  /* add k to y's exponent */
	}
    }
  return y;
}
weak_alias (__expm1, expm1)
#ifdef NO_LONG_DOUBLE
strong_alias (__expm1, __expm1l)
weak_alias (__expm1, expm1l)
#endif
