]> sourceware.org Git - glibc.git/blame - sysdeps/ieee754/ldbl-128/s_expm1l.c
Move math_check_force_underflow macros to separate math-underflow.h.
[glibc.git] / sysdeps / ieee754 / ldbl-128 / s_expm1l.c
CommitLineData
ef25b29e
AJ
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
9c84384c 38/* Copyright 2001 by Stephen L. Moshier
cc7375ce
RM
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
59ba27a6
PE
51 License along with this library; if not, see
52 <http://www.gnu.org/licenses/>. */
cc7375ce 53
ef25b29e
AJ
54
55
7f3394bd 56#include <errno.h>
ce9c5b3e 57#include <float.h>
1ed0291c
RH
58#include <math.h>
59#include <math_private.h>
8f5b00d3 60#include <math-underflow.h>
fd3b4e7c 61#include <libm-alias-ldouble.h>
ef25b29e
AJ
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
15089e04 67static const _Float128
02bbfb41
PM
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),
ef25b29e
AJ
84 /* Q8 = 1.000000000000000000000000000000000000000E0 */
85/* C1 + C2 = ln 2 */
86
02bbfb41
PM
87 C1 = L(6.93145751953125E-1),
88 C2 = L(1.428606820309417232121458176568075500134E-6),
ef25b29e 89/* ln 2^-114 */
02bbfb41 90 minarg = L(-7.9018778583833765273564461846232128760607E1), big = L(1e4932);
ef25b29e
AJ
91
92
15089e04
PM
93_Float128
94__expm1l (_Float128 x)
ef25b29e 95{
15089e04 96 _Float128 px, qx, xx;
ef25b29e
AJ
97 int32_t ix, sign;
98 ieee854_long_double_shape_type u;
99 int k;
100
ef25b29e
AJ
101 /* Detect infinity and NaN. */
102 u.value = x;
103 ix = u.parts32.w0;
104 sign = ix & 0x80000000;
105 ix &= 0x7fffffff;
2a8ab7f2
DM
106 if (!sign && ix >= 0x40060000)
107 {
108 /* If num is positive and exp >= 6 use plain exp. */
109 return __expl (x);
110 }
ef25b29e
AJ
111 if (ix >= 0x7fff0000)
112 {
8124ac3e 113 /* Infinity (which must be negative infinity). */
ef25b29e 114 if (((ix & 0xffff) | u.parts32.w1 | u.parts32.w2 | u.parts32.w3) == 0)
02bbfb41 115 return -1;
59e53a78
JM
116 /* NaN. Invalid exception if signaling. */
117 return x + x;
ef25b29e
AJ
118 }
119
514abd20
AJ
120 /* expm1(+- 0) = +- 0. */
121 if ((ix == 0) && (u.parts32.w1 | u.parts32.w2 | u.parts32.w3) == 0)
122 return x;
1f5649f8 123
514abd20
AJ
124 /* Minimum value. */
125 if (x < minarg)
02bbfb41 126 return (4.0/big - 1);
514abd20 127
a04bb330
JM
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. */
02bbfb41 131 if (fabsl (x) < L(0x1p-113))
a04bb330 132 {
d96164c3 133 math_check_force_underflow (x);
a04bb330
JM
134 return x;
135 }
ce9c5b3e 136
ef25b29e
AJ
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
02bbfb41 163 px = __ldexpl (1, k);
ef25b29e
AJ
164 x = px * qx + (px - 1.0);
165 return x;
166}
76f2646f 167libm_hidden_def (__expm1l)
fd3b4e7c 168libm_alias_ldouble (__expm1, expm1)
This page took 0.533551 seconds and 5 git commands to generate.