1 /*							expm1l.c
2  *
3  *	Exponential function, minus 1
4  *      128-bit long double precision
5  *
6  *
7  *
8  * SYNOPSIS:
9  *
10  * long double x, y, expm1l();
11  *
12  * y = expm1l( x );
13  *
14  *
15  *
16  * DESCRIPTION:
17  *
18  * Returns e (2.71828...) raised to the x power, minus one.
19  *
20  * Range reduction is accomplished by separating the argument
21  * into an integer k and fraction f such that
22  *
23  *     x    k  f
24  *    e  = 2  e.
25  *
26  * An expansion x + .5 x^2 + x^3 R(x) approximates exp(f) - 1
27  * in the basic range [-0.5 ln 2, 0.5 ln 2].
28  *
29  *
30  * ACCURACY:
31  *
32  *                      Relative error:
33  * arithmetic   domain     # trials      peak         rms
34  *    IEEE    -79,+MAXLOG    100,000     1.7e-34     4.5e-35
35  *
36  */
37 
38 /* Copyright 2001 by Stephen L. Moshier
39 
40     This library is free software; you can redistribute it and/or
41     modify it under the terms of the GNU Lesser General Public
42     License as published by the Free Software Foundation; either
43     version 2.1 of the License, or (at your option) any later version.
44 
45     This library is distributed in the hope that it will be useful,
46     but WITHOUT ANY WARRANTY; without even the implied warranty of
47     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
48     Lesser General Public License for more details.
49 
50     You should have received a copy of the GNU Lesser General Public
51     License along with this library; if not, see
52     <https://www.gnu.org/licenses/>.  */
53 
54 
55 
56 #include <errno.h>
57 #include <float.h>
58 #include <math.h>
59 #include <math_private.h>
60 #include <math-underflow.h>
61 #include <libm-alias-ldouble.h>
62 
63 /* exp(x) - 1 = x + 0.5 x^2 + x^3 P(x)/Q(x)
64    -.5 ln 2  <  x  <  .5 ln 2
65    Theoretical peak relative error = 8.1e-36  */
66 
67 static const _Float128
68   P0 = L(2.943520915569954073888921213330863757240E8),
69   P1 = L(-5.722847283900608941516165725053359168840E7),
70   P2 = L(8.944630806357575461578107295909719817253E6),
71   P3 = L(-7.212432713558031519943281748462837065308E5),
72   P4 = L(4.578962475841642634225390068461943438441E4),
73   P5 = L(-1.716772506388927649032068540558788106762E3),
74   P6 = L(4.401308817383362136048032038528753151144E1),
75   P7 = L(-4.888737542888633647784737721812546636240E-1),
76   Q0 = L(1.766112549341972444333352727998584753865E9),
77   Q1 = L(-7.848989743695296475743081255027098295771E8),
78   Q2 = L(1.615869009634292424463780387327037251069E8),
79   Q3 = L(-2.019684072836541751428967854947019415698E7),
80   Q4 = L(1.682912729190313538934190635536631941751E6),
81   Q5 = L(-9.615511549171441430850103489315371768998E4),
82   Q6 = L(3.697714952261803935521187272204485251835E3),
83   Q7 = L(-8.802340681794263968892934703309274564037E1),
84   /* Q8 = 1.000000000000000000000000000000000000000E0 */
85 /* C1 + C2 = ln 2 */
86 
87   C1 = L(6.93145751953125E-1),
88   C2 = L(1.428606820309417232121458176568075500134E-6),
89 /* ln 2^-114 */
90   minarg = L(-7.9018778583833765273564461846232128760607E1), big = L(1e4932);
91 
92 
93 _Float128
__expm1l(_Float128 x)94 __expm1l (_Float128 x)
95 {
96   _Float128 px, qx, xx;
97   int32_t ix, sign;
98   ieee854_long_double_shape_type u;
99   int k;
100 
101   /* Detect infinity and NaN.  */
102   u.value = x;
103   ix = u.parts32.w0;
104   sign = ix & 0x80000000;
105   ix &= 0x7fffffff;
106   if (!sign && ix >= 0x40060000)
107     {
108       /* If num is positive and exp >= 6 use plain exp.  */
109       return __expl (x);
110     }
111   if (ix >= 0x7fff0000)
112     {
113       /* Infinity (which must be negative infinity). */
114       if (((ix & 0xffff) | u.parts32.w1 | u.parts32.w2 | u.parts32.w3) == 0)
115 	return -1;
116       /* NaN.  Invalid exception if signaling.  */
117       return x + x;
118     }
119 
120   /* expm1(+- 0) = +- 0.  */
121   if ((ix == 0) && (u.parts32.w1 | u.parts32.w2 | u.parts32.w3) == 0)
122     return x;
123 
124   /* Minimum value.  */
125   if (x < minarg)
126     return (4.0/big - 1);
127 
128   /* Avoid internal underflow when result does not underflow, while
129      ensuring underflow (without returning a zero of the wrong sign)
130      when the result does underflow.  */
131   if (fabsl (x) < L(0x1p-113))
132     {
133       math_check_force_underflow (x);
134       return x;
135     }
136 
137   /* Express x = ln 2 (k + remainder), remainder not exceeding 1/2. */
138   xx = C1 + C2;			/* ln 2. */
139   px = floorl (0.5 + x / xx);
140   k = px;
141   /* remainder times ln 2 */
142   x -= px * C1;
143   x -= px * C2;
144 
145   /* Approximate exp(remainder ln 2).  */
146   px = (((((((P7 * x
147 	      + P6) * x
148 	     + P5) * x + P4) * x + P3) * x + P2) * x + P1) * x + P0) * x;
149 
150   qx = (((((((x
151 	      + Q7) * x
152 	     + Q6) * x + Q5) * x + Q4) * x + Q3) * x + Q2) * x + Q1) * x + Q0;
153 
154   xx = x * x;
155   qx = x + (0.5 * xx + xx * px / qx);
156 
157   /* exp(x) = exp(k ln 2) exp(remainder ln 2) = 2^k exp(remainder ln 2).
158 
159   We have qx = exp(remainder ln 2) - 1, so
160   exp(x) - 1 = 2^k (qx + 1) - 1
161              = 2^k qx + 2^k - 1.  */
162 
163   px = __ldexpl (1, k);
164   x = px * qx + (px - 1.0);
165   return x;
166 }
167 libm_hidden_def (__expm1l)
168 libm_alias_ldouble (__expm1, expm1)
169