Upload Tizen:Base source
[external/eglibc.git] / sysdeps / ieee754 / ldbl-128 / e_expl.c
1 /* Quad-precision floating point e^x.
2    Copyright (C) 1999 Free Software Foundation, Inc.
3    This file is part of the GNU C Library.
4    Contributed by Jakub Jelinek <jj@ultra.linux.cz>
5    Partly based on double-precision code
6    by Geoffrey Keating <geoffk@ozemail.com.au>
7
8    The GNU C Library is free software; you can redistribute it and/or
9    modify it under the terms of the GNU Lesser General Public
10    License as published by the Free Software Foundation; either
11    version 2.1 of the License, or (at your option) any later version.
12
13    The GNU C Library is distributed in the hope that it will be useful,
14    but WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16    Lesser General Public License for more details.
17
18    You should have received a copy of the GNU Lesser General Public
19    License along with the GNU C Library; if not, write to the Free
20    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
21    02111-1307 USA.  */
22
23 /* The basic design here is from
24    Abraham Ziv, "Fast Evaluation of Elementary Mathematical Functions with
25    Correctly Rounded Last Bit", ACM Trans. Math. Soft., 17 (3), September 1991,
26    pp. 410-423.
27
28    We work with number pairs where the first number is the high part and
29    the second one is the low part. Arithmetic with the high part numbers must
30    be exact, without any roundoff errors.
31
32    The input value, X, is written as
33    X = n * ln(2)_0 + arg1[t1]_0 + arg2[t2]_0 + x
34        - n * ln(2)_1 + arg1[t1]_1 + arg2[t2]_1 + xl
35
36    where:
37    - n is an integer, 16384 >= n >= -16495;
38    - ln(2)_0 is the first 93 bits of ln(2), and |ln(2)_0-ln(2)-ln(2)_1| < 2^-205
39    - t1 is an integer, 89 >= t1 >= -89
40    - t2 is an integer, 65 >= t2 >= -65
41    - |arg1[t1]-t1/256.0| < 2^-53
42    - |arg2[t2]-t2/32768.0| < 2^-53
43    - x + xl is whatever is left, |x + xl| < 2^-16 + 2^-53
44
45    Then e^x is approximated as
46
47    e^x = 2^n_1 ( 2^n_0 e^(arg1[t1]_0 + arg1[t1]_1) e^(arg2[t2]_0 + arg2[t2]_1)
48                + 2^n_0 e^(arg1[t1]_0 + arg1[t1]_1) e^(arg2[t2]_0 + arg2[t2]_1)
49                  * p (x + xl + n * ln(2)_1))
50    where:
51    - p(x) is a polynomial approximating e(x)-1
52    - e^(arg1[t1]_0 + arg1[t1]_1) is obtained from a table
53    - e^(arg2[t2]_0 + arg2[t2]_1) likewise
54    - n_1 + n_0 = n, so that |n_0| < -LDBL_MIN_EXP-1.
55
56    If it happens that n_1 == 0 (this is the usual case), that multiplication
57    is omitted.
58    */
59
60 #ifndef _GNU_SOURCE
61 #define _GNU_SOURCE
62 #endif
63 #include <float.h>
64 #include <ieee754.h>
65 #include <math.h>
66 #include <fenv.h>
67 #include <inttypes.h>
68 #include <math_private.h>
69 #include <stdlib.h>
70 #include "t_expl.h"
71
72 static const long double C[] = {
73 /* Smallest integer x for which e^x overflows.  */
74 #define himark C[0]
75  11356.523406294143949491931077970765L,
76  
77 /* Largest integer x for which e^x underflows.  */
78 #define lomark C[1]
79 -11433.4627433362978788372438434526231L,
80
81 /* 3x2^96 */
82 #define THREEp96 C[2]
83  59421121885698253195157962752.0L,
84
85 /* 3x2^103 */
86 #define THREEp103 C[3]
87  30423614405477505635920876929024.0L,
88
89 /* 3x2^111 */
90 #define THREEp111 C[4]
91  7788445287802241442795744493830144.0L,
92
93 /* 1/ln(2) */
94 #define M_1_LN2 C[5]
95  1.44269504088896340735992468100189204L,
96
97 /* first 93 bits of ln(2) */
98 #define M_LN2_0 C[6]
99  0.693147180559945309417232121457981864L,
100
101 /* ln2_0 - ln(2) */
102 #define M_LN2_1 C[7]
103 -1.94704509238074995158795957333327386E-31L,
104
105 /* very small number */
106 #define TINY C[8]
107  1.0e-4900L,
108
109 /* 2^16383 */
110 #define TWO16383 C[9]
111  5.94865747678615882542879663314003565E+4931L,
112
113 /* 256 */
114 #define TWO8 C[10]
115  256.0L,
116
117 /* 32768 */
118 #define TWO15 C[11]
119  32768.0L,
120
121 /* Chebyshev polynom coeficients for (exp(x)-1)/x */
122 #define P1 C[12]
123 #define P2 C[13]
124 #define P3 C[14]
125 #define P4 C[15]
126 #define P5 C[16]
127 #define P6 C[17]
128  0.5L,
129  1.66666666666666666666666666666666683E-01L,
130  4.16666666666666666666654902320001674E-02L,
131  8.33333333333333333333314659767198461E-03L,
132  1.38888888889899438565058018857254025E-03L,
133  1.98412698413981650382436541785404286E-04L,
134 };
135
136 long double
137 __ieee754_expl (long double x)
138 {
139   /* Check for usual case.  */
140   if (isless (x, himark) && isgreater (x, lomark))
141     {
142       int tval1, tval2, unsafe, n_i;
143       long double x22, n, t, result, xl;
144       union ieee854_long_double ex2_u, scale_u;
145       fenv_t oldenv;
146
147       feholdexcept (&oldenv);
148 #ifdef FE_TONEAREST
149       fesetround (FE_TONEAREST);
150 #endif
151
152       /* Calculate n.  */
153       n = x * M_1_LN2 + THREEp111;
154       n -= THREEp111;
155       x = x - n * M_LN2_0;
156       xl = n * M_LN2_1;
157
158       /* Calculate t/256.  */
159       t = x + THREEp103;
160       t -= THREEp103;
161
162       /* Compute tval1 = t.  */
163       tval1 = (int) (t * TWO8);
164
165       x -= __expl_table[T_EXPL_ARG1+2*tval1];
166       xl -= __expl_table[T_EXPL_ARG1+2*tval1+1];
167
168       /* Calculate t/32768.  */
169       t = x + THREEp96;
170       t -= THREEp96;
171
172       /* Compute tval2 = t.  */
173       tval2 = (int) (t * TWO15);
174
175       x -= __expl_table[T_EXPL_ARG2+2*tval2];
176       xl -= __expl_table[T_EXPL_ARG2+2*tval2+1];
177
178       x = x + xl;
179
180       /* Compute ex2 = 2^n_0 e^(argtable[tval1]) e^(argtable[tval2]).  */
181       ex2_u.d = __expl_table[T_EXPL_RES1 + tval1]
182                 * __expl_table[T_EXPL_RES2 + tval2];
183       n_i = (int)n;
184       /* 'unsafe' is 1 iff n_1 != 0.  */
185       unsafe = abs(n_i) >= -LDBL_MIN_EXP - 1;
186       ex2_u.ieee.exponent += n_i >> unsafe;
187
188       /* Compute scale = 2^n_1.  */
189       scale_u.d = 1.0L;
190       scale_u.ieee.exponent += n_i - (n_i >> unsafe);
191
192       /* Approximate e^x2 - 1, using a seventh-degree polynomial,
193          with maximum error in [-2^-16-2^-53,2^-16+2^-53]
194          less than 4.8e-39.  */
195       x22 = x + x*x*(P1+x*(P2+x*(P3+x*(P4+x*(P5+x*P6)))));
196
197       /* Return result.  */
198       fesetenv (&oldenv);
199
200       result = x22 * ex2_u.d + ex2_u.d;
201
202       /* Now we can test whether the result is ultimate or if we are unsure.
203          In the later case we should probably call a mpn based routine to give
204          the ultimate result.
205          Empirically, this routine is already ultimate in about 99.9986% of
206          cases, the test below for the round to nearest case will be false
207          in ~ 99.9963% of cases.
208          Without proc2 routine maximum error which has been seen is
209          0.5000262 ulp.
210
211           union ieee854_long_double ex3_u;
212
213           #ifdef FE_TONEAREST
214             fesetround (FE_TONEAREST);
215           #endif
216           ex3_u.d = (result - ex2_u.d) - x22 * ex2_u.d;
217           ex2_u.d = result;
218           ex3_u.ieee.exponent += LDBL_MANT_DIG + 15 + IEEE854_LONG_DOUBLE_BIAS
219                                  - ex2_u.ieee.exponent;
220           n_i = abs (ex3_u.d);
221           n_i = (n_i + 1) / 2;
222           fesetenv (&oldenv);
223           #ifdef FE_TONEAREST
224           if (fegetround () == FE_TONEAREST)
225             n_i -= 0x4000;
226           #endif
227           if (!n_i) {
228             return __ieee754_expl_proc2 (origx);
229           }
230        */
231       if (!unsafe)
232         return result;
233       else
234         return result * scale_u.d;
235     }
236   /* Exceptional cases:  */
237   else if (isless (x, himark))
238     {
239       if (__isinfl (x))
240         /* e^-inf == 0, with no error.  */
241         return 0;
242       else
243         /* Underflow */
244         return TINY * TINY;
245     }
246   else
247     /* Return x, if x is a NaN or Inf; or overflow, otherwise.  */
248     return TWO16383*x;
249 }