diff options
Diffstat (limited to 'sysdeps/ieee754')
-rw-r--r-- | sysdeps/ieee754/dbl-64/e_exp.c | 62 | ||||
-rw-r--r-- | sysdeps/ieee754/dbl-64/slowexp.c | 86 | ||||
-rw-r--r-- | sysdeps/ieee754/dbl-64/uexp.h | 3 |
3 files changed, 18 insertions, 133 deletions
diff --git a/sysdeps/ieee754/dbl-64/e_exp.c b/sysdeps/ieee754/dbl-64/e_exp.c index 7a9daa5858..1bcb382c77 100644 --- a/sysdeps/ieee754/dbl-64/e_exp.c +++ b/sysdeps/ieee754/dbl-64/e_exp.c @@ -23,10 +23,10 @@ /* exp1 */ /* */ /* FILES NEEDED:dla.h endian.h mpa.h mydefs.h uexp.h */ -/* mpa.c mpexp.x slowexp.c */ +/* mpa.c mpexp.x */ /* */ /* An ultimate exp routine. Given an IEEE double machine number x */ -/* it computes the correctly rounded (to nearest) value of e^x */ +/* it computes an almost correctly rounded (to nearest) value of e^x */ /* Assumption: Machine arithmetic operations are performed in */ /* round to nearest mode of IEEE 754 standard. */ /* */ @@ -46,10 +46,6 @@ # define SECTION #endif -double __slowexp (double); - -/* An ultimate exp routine. Given an IEEE double machine number x it computes - the correctly rounded (to nearest) value of e^x. */ double SECTION __ieee754_exp (double x) @@ -93,17 +89,10 @@ __ieee754_exp (double x) rem = (bet + bet * eps) + al * eps; res = al + rem; - cor = (al - res) + rem; - if (res == (res + cor * err_0)) - { - retval = res * binexp.x; - goto ret; - } - else - { - retval = __slowexp (x); - goto ret; - } /*if error is over bound */ + /* Maximum relative error is 7.8e-22 (70.1 bits). + Maximum ULP error is 0.500007. */ + retval = res * binexp.x; + goto ret; } if (n <= smallint) @@ -166,38 +155,22 @@ __ieee754_exp (double x) if (ex >= -1022) { binexp.i[HIGH_HALF] = (1023 + ex) << 20; - if (res == (res + cor * err_0)) - { - retval = res * binexp.x; - goto ret; - } - else - { - retval = __slowexp (x); - goto check_uflow_ret; - } /*if error is over bound */ + /* Does not underflow: res >= 1.0, binexp >= 0x1p-1022 + Maximum relative error is 7.8e-22 (70.1 bits). + Maximum ULP error is 0.500007. */ + retval = res * binexp.x; + goto ret; } ex = -(1022 + ex); binexp.i[HIGH_HALF] = (1023 - ex) << 20; res *= binexp.x; cor *= binexp.x; - eps = 1.0000000001 + err_0 * binexp.x; t = 1.0 + res; y = ((1.0 - t) + res) + cor; res = t + y; - cor = (t - res) + y; - if (res == (res + eps * cor)) - { - binexp.i[HIGH_HALF] = 0x00100000; - retval = (res - 1.0) * binexp.x; - goto check_uflow_ret; - } - else - { - retval = __slowexp (x); - goto check_uflow_ret; - } /* if error is over bound */ - check_uflow_ret: + /* Maximum ULP error is 0.5000035. */ + binexp.i[HIGH_HALF] = 0x00100000; + retval = (res - 1.0) * binexp.x; if (retval < DBL_MIN) { double force_underflow = tiny * tiny; @@ -210,10 +183,9 @@ __ieee754_exp (double x) else { binexp.i[HIGH_HALF] = (junk1.i[LOW_HALF] + 767) << 20; - if (res == (res + cor * err_0)) - retval = res * binexp.x * t256.x; - else - retval = __slowexp (x); + /* Maximum relative error is 7.8e-22 (70.1 bits). + Maximum ULP error is 0.500007. */ + retval = res * binexp.x * t256.x; if (isinf (retval)) goto ret_huge; else diff --git a/sysdeps/ieee754/dbl-64/slowexp.c b/sysdeps/ieee754/dbl-64/slowexp.c deleted file mode 100644 index ba5617466c..0000000000 --- a/sysdeps/ieee754/dbl-64/slowexp.c +++ /dev/null @@ -1,86 +0,0 @@ -/* - * IBM Accurate Mathematical Library - * written by International Business Machines Corp. - * Copyright (C) 2001-2018 Free Software Foundation, Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation; either version 2.1 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, see <http://www.gnu.org/licenses/>. - */ -/**************************************************************************/ -/* MODULE_NAME:slowexp.c */ -/* */ -/* FUNCTION:slowexp */ -/* */ -/* FILES NEEDED:mpa.h */ -/* mpa.c mpexp.c */ -/* */ -/*Converting from double precision to Multi-precision and calculating */ -/* e^x */ -/**************************************************************************/ -#include <math_private.h> - -#include <stap-probe.h> - -#ifndef USE_LONG_DOUBLE_FOR_MP -# include "mpa.h" -void __mpexp (mp_no *x, mp_no *y, int p); -#endif - -#ifndef SECTION -# define SECTION -#endif - -/*Converting from double precision to Multi-precision and calculating e^x */ -double -SECTION -__slowexp (double x) -{ -#ifndef USE_LONG_DOUBLE_FOR_MP - double w, z, res, eps = 3.0e-26; - int p; - mp_no mpx, mpy, mpz, mpw, mpeps, mpcor; - - /* Use the multiple precision __MPEXP function to compute the exponential - First at 144 bits and if it is not accurate enough, at 768 bits. */ - p = 6; - __dbl_mp (x, &mpx, p); - __mpexp (&mpx, &mpy, p); - __dbl_mp (eps, &mpeps, p); - __mul (&mpeps, &mpy, &mpcor, p); - __add (&mpy, &mpcor, &mpw, p); - __sub (&mpy, &mpcor, &mpz, p); - __mp_dbl (&mpw, &w, p); - __mp_dbl (&mpz, &z, p); - if (w == z) - { - /* Track how often we get to the slow exp code plus - its input/output values. */ - LIBC_PROBE (slowexp_p6, 2, &x, &w); - return w; - } - else - { - p = 32; - __dbl_mp (x, &mpx, p); - __mpexp (&mpx, &mpy, p); - __mp_dbl (&mpy, &res, p); - - /* Track how often we get to the uber-slow exp code plus - its input/output values. */ - LIBC_PROBE (slowexp_p32, 2, &x, &res); - return res; - } -#else - return (double) __ieee754_expl((long double)x); -#endif -} diff --git a/sysdeps/ieee754/dbl-64/uexp.h b/sysdeps/ieee754/dbl-64/uexp.h index 2edf530b69..64ab2c8fca 100644 --- a/sysdeps/ieee754/dbl-64/uexp.h +++ b/sysdeps/ieee754/dbl-64/uexp.h @@ -29,8 +29,7 @@ #include "mydefs.h" -const static double zero = 0.0, hhuge = 1.0e300, tiny = 1.0e-300, -err_0 = 1.000014; +const static double zero = 0.0, hhuge = 1.0e300, tiny = 1.0e-300; const static int4 bigint = 0x40862002, badint = 0x40876000,smallint = 0x3C8fffff; const static int4 hugeint = 0x7FFFFFFF, infint = 0x7ff00000; |