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