about summary refs log tree commit diff
path: root/sysdeps/ieee754/dbl-64/e_exp.c
diff options
context:
space:
mode:
authorSzabolcs Nagy <szabolcs.nagy@arm.com>2018-01-30 14:48:22 +0000
committerSzabolcs Nagy <szabolcs.nagy@arm.com>2018-02-12 11:33:33 +0000
commitde800d83059dbedb7d151580f0a3bdc9eaf37340 (patch)
tree9c35197ab9d9788c73bd6aa5d7d19eb90979f629 /sysdeps/ieee754/dbl-64/e_exp.c
parentc3d466cba1692708a19c6ff829d0386c83a0c6e5 (diff)
downloadglibc-de800d83059dbedb7d151580f0a3bdc9eaf37340.tar.gz
glibc-de800d83059dbedb7d151580f0a3bdc9eaf37340.tar.xz
glibc-de800d83059dbedb7d151580f0a3bdc9eaf37340.zip
Remove slow paths from exp
Remove the __slowexp code, so exp is no longer correctly rounded.  The
result is computed to about 70 bits precision so the worst case ulp
error is about 0.500007 in nearest rounding mode.

	* manual/probes.texi: Remove slowexp probes.
	* math/Makefile: Remove slowexp.
	* sysdeps/generic/math_private.h (__slowexp): Remove.
	* sysdeps/ieee754/dbl-64/e_exp.c (__ieee754_exp): Remove __slowexp and
	document error bounds.
	* sysdeps/i386/fpu/slowexp.c: Remove.
	* sysdeps/ia64/fpu/slowexp.c: Remove.
	* sysdeps/ieee754/dbl-64/slowexp.c: Remove.
	* sysdeps/ieee754/dbl-64/uexp.h (err_0): Remove.
	* sysdeps/m68k/m680x0/fpu/slowexp.c: Remove.
	* sysdeps/powerpc/power4/fpu/Makefile (CPPFLAGS-slowexp.c): Remove.
	* sysdeps/x86_64/fpu/multiarch/Makefile: Remove slowexp-fma.
	* sysdeps/x86_64/fpu/multiarch/e_exp-avx.c (__slowexp): Remove.
	* sysdeps/x86_64/fpu/multiarch/e_exp-fma.c (__slowexp): Remove.
	* sysdeps/x86_64/fpu/multiarch/e_exp-fma4.c (__slowexp): Remove.
	* sysdeps/x86_64/fpu/multiarch/slowexp-avx.c: Remove.
	* sysdeps/x86_64/fpu/multiarch/slowexp-fma.c: Remove.
	* sysdeps/x86_64/fpu/multiarch/slowexp-fma4.c: Remove.
Diffstat (limited to 'sysdeps/ieee754/dbl-64/e_exp.c')
-rw-r--r--sysdeps/ieee754/dbl-64/e_exp.c62
1 files changed, 17 insertions, 45 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