This is the mail archive of the glibc-cvs@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

GNU C Library master sources branch, master, updated. glibc-2.15-276-g28afd92


This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "GNU C Library master sources".

The branch, master has been updated
       via  28afd92dbdb4fef4358051aad5cb944a9527a4b5 (commit)
      from  b1eeb65d491c0fec94b29cfbbd2e384c9f3765cc (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
http://sources.redhat.com/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=28afd92dbdb4fef4358051aad5cb944a9527a4b5

commit 28afd92dbdb4fef4358051aad5cb944a9527a4b5
Author: Joseph Myers <joseph@codesourcery.com>
Date:   Fri Mar 2 15:12:53 2012 +0000

    Fix exp in non-default rounding modes (bug 3976).

diff --git a/ChangeLog b/ChangeLog
index 29c5dc2..a10bb8b 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,17 @@
+2012-03-02  Joseph Myers  <joseph@codesourcery.com>
+
+	[BZ #3976]
+	* sysdeps/ieee754/dbl-64/e_exp.c: Include <fenv.h>.
+	(__ieee754_exp): Save and restore rounding mode and use
+	round-to-nearest for all computations.
+	* math/libm-test.inc (exp_test_tonearest): New function.
+	(exp_test_towardzero): Likewise.
+	(exp_test_downward): Likewise.
+	(exp_test_upward): Likewise.
+	(main): Call the new functions.
+	* sysdeps/i386/fpu/libm-test-ulps: Update.
+	* sysdeps/x86_64/fpu/libm-test-ulps: Likewise.
+
 2012-03-01  Chris Demetriou  <cgd@google.com>
 
 	* sysdeps/gnu/errlist-compat.awk: Don't depend on AWK internals to
diff --git a/math/libm-test.inc b/math/libm-test.inc
index 9f7d489..5bc0d40 100644
--- a/math/libm-test.inc
+++ b/math/libm-test.inc
@@ -2532,6 +2532,114 @@ exp_test (void)
 
 
 static void
+exp_test_tonearest (void)
+{
+  int save_round_mode;
+  errno = 0;
+  FUNC(exp) (0);
+  if (errno == ENOSYS)
+    /* Function not implemented.  */
+    return;
+
+  START (exp_tonearest);
+
+  save_round_mode = fegetround ();
+
+  if (!fesetround (FE_TONEAREST))
+    {
+      TEST_f_f (exp, 1, M_El);
+      TEST_f_f (exp, 2, M_E2l);
+      TEST_f_f (exp, 3, M_E3l);
+    }
+
+  fesetround (save_round_mode);
+
+  END (exp_tonearest);
+}
+
+
+static void
+exp_test_towardzero (void)
+{
+  int save_round_mode;
+  errno = 0;
+  FUNC(exp) (0);
+  if (errno == ENOSYS)
+    /* Function not implemented.  */
+    return;
+
+  START (exp_towardzero);
+
+  save_round_mode = fegetround ();
+
+  if (!fesetround (FE_TOWARDZERO))
+    {
+      TEST_f_f (exp, 1, M_El);
+      TEST_f_f (exp, 2, M_E2l);
+      TEST_f_f (exp, 3, M_E3l);
+    }
+
+  fesetround (save_round_mode);
+
+  END (exp_towardzero);
+}
+
+
+static void
+exp_test_downward (void)
+{
+  int save_round_mode;
+  errno = 0;
+  FUNC(exp) (0);
+  if (errno == ENOSYS)
+    /* Function not implemented.  */
+    return;
+
+  START (exp_downward);
+
+  save_round_mode = fegetround ();
+
+  if (!fesetround (FE_DOWNWARD))
+    {
+      TEST_f_f (exp, 1, M_El);
+      TEST_f_f (exp, 2, M_E2l);
+      TEST_f_f (exp, 3, M_E3l);
+    }
+
+  fesetround (save_round_mode);
+
+  END (exp_downward);
+}
+
+
+static void
+exp_test_upward (void)
+{
+  int save_round_mode;
+  errno = 0;
+  FUNC(exp) (0);
+  if (errno == ENOSYS)
+    /* Function not implemented.  */
+    return;
+
+  START (exp_upward);
+
+  save_round_mode = fegetround ();
+
+  if (!fesetround (FE_UPWARD))
+    {
+      TEST_f_f (exp, 1, M_El);
+      TEST_f_f (exp, 2, M_E2l);
+      TEST_f_f (exp, 3, M_E3l);
+    }
+
+  fesetround (save_round_mode);
+
+  END (exp_upward);
+}
+
+
+static void
 exp10_test (void)
 {
   errno = 0;
@@ -6400,6 +6508,10 @@ main (int argc, char **argv)
 
   /* Exponential and logarithmic functions:  */
   exp_test ();
+  exp_test_tonearest ();
+  exp_test_towardzero ();
+  exp_test_downward ();
+  exp_test_upward ();
   exp10_test ();
   exp2_test ();
   expm1_test ();
diff --git a/sysdeps/i386/fpu/libm-test-ulps b/sysdeps/i386/fpu/libm-test-ulps
index 5629397..389253e 100644
--- a/sysdeps/i386/fpu/libm-test-ulps
+++ b/sysdeps/i386/fpu/libm-test-ulps
@@ -460,6 +460,51 @@ Test "exp10 (3) == 1000":
 ildouble: 8
 ldouble: 8
 
+# exp_downward
+Test "exp_downward (1) == e":
+ildouble: 1
+ldouble: 1
+Test "exp_downward (2) == e^2":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 2
+ldouble: 2
+Test "exp_downward (3) == e^3":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+# exp_towardzero
+Test "exp_towardzero (1) == e":
+ildouble: 1
+ldouble: 1
+Test "exp_towardzero (2) == e^2":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 2
+ldouble: 2
+Test "exp_towardzero (3) == e^3":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+# exp_upward
+Test "exp_upward (1) == e":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+
 # expm1
 Test "expm1 (1) == M_El - 1.0":
 ildouble: 1
@@ -1184,6 +1229,28 @@ Function: "exp10":
 ildouble: 8
 ldouble: 8
 
+Function: "exp_downward":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 2
+ldouble: 2
+
+Function: "exp_towardzero":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+ildouble: 2
+ldouble: 2
+
+Function: "exp_upward":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+
 Function: "expm1":
 ildouble: 1
 ldouble: 1
diff --git a/sysdeps/ieee754/dbl-64/e_exp.c b/sysdeps/ieee754/dbl-64/e_exp.c
index cfdb8e2..8231c56 100644
--- a/sysdeps/ieee754/dbl-64/e_exp.c
+++ b/sysdeps/ieee754/dbl-64/e_exp.c
@@ -1,7 +1,7 @@
 /*
  * IBM Accurate Mathematical Library
  * written by International Business Machines Corp.
- * Copyright (C) 2001, 2011 Free Software Foundation
+ * Copyright (C) 2001-2012 Free Software Foundation
  *
  * 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
@@ -38,6 +38,7 @@
 #include "MathLib.h"
 #include "uexp.tbl"
 #include "math_private.h"
+#include <fenv.h>
 
 #ifndef SECTION
 # define SECTION
@@ -58,6 +59,10 @@ __ieee754_exp(double x) {
   int4 k;
 #endif
   int4 i,j,m,n,ex;
+  fenv_t env;
+  double retval;
+
+  libc_feholdexcept_setround (&env, FE_TONEAREST);
 
   junk1.x = x;
   m = junk1.i[HIGH_HALF];
@@ -90,18 +95,19 @@ __ieee754_exp(double x) {
     rem=(bet + bet*eps)+al*eps;
     res = al + rem;
     cor = (al - res) + rem;
-    if  (res == (res+cor*err_0)) return res*binexp.x;
-    else return __slowexp(x); /*if error is over bound */
+    if  (res == (res+cor*err_0)) { retval = res*binexp.x; goto ret; }
+    else { retval = __slowexp(x); goto ret; } /*if error is over bound */
   }
 
-  if (n <= smallint) return 1.0;
+  if (n <= smallint) { retval = 1.0; goto ret; }
 
   if (n >= badint) {
-    if (n > infint) return(x+x);               /* x is NaN */
-    if (n < infint) return ( (x>0) ? (hhuge*hhuge) : (tiny*tiny) );
+    if (n > infint) { retval = x+x; goto ret; }               /* x is NaN */
+    if (n < infint) { retval = (x>0) ? (hhuge*hhuge) : (tiny*tiny); goto ret; }
     /* x is finite,  cause either overflow or underflow  */
-    if (junk1.i[LOW_HALF] != 0)  return (x+x);                /*  x is NaN  */
-    return ((x>0)?inf.x:zero );             /* |x| = inf;  return either inf or 0 */
+    if (junk1.i[LOW_HALF] != 0) { retval = x+x; goto ret; } /*  x is NaN  */
+    retval = (x>0)?inf.x:zero;             /* |x| = inf;  return either inf or 0 */
+    goto ret;
   }
 
   y = x*log2e.x + three51.x;
@@ -126,8 +132,8 @@ __ieee754_exp(double x) {
     if (res < 1.0) {res+=res; cor+=cor; ex-=1;}
     if (ex >=-1022) {
       binexp.i[HIGH_HALF] = (1023+ex)<<20;
-      if  (res == (res+cor*err_0)) return res*binexp.x;
-      else return __slowexp(x); /*if error is over bound */
+      if  (res == (res+cor*err_0)) { retval = res*binexp.x; goto ret; }
+      else { retval = __slowexp(x); goto ret; } /*if error is over bound */
     }
     ex = -(1022+ex);
     binexp.i[HIGH_HALF] = (1023-ex)<<20;
@@ -140,15 +146,19 @@ __ieee754_exp(double x) {
     cor = (t-res)+y;
     if (res == (res + eps*cor))
     { binexp.i[HIGH_HALF] = 0x00100000;
-      return (res-1.0)*binexp.x;
+      retval = (res-1.0)*binexp.x;
+      goto ret;
     }
-    else return __slowexp(x); /*   if error is over bound    */
+    else { retval = __slowexp(x); goto ret; } /*   if error is over bound    */
   }
   else {
     binexp.i[HIGH_HALF] =(junk1.i[LOW_HALF]+767)<<20;
-    if  (res == (res+cor*err_0)) return res*binexp.x*t256.x;
-    else return __slowexp(x);
+    if (res == (res+cor*err_0)) { retval = res*binexp.x*t256.x; goto ret; }
+    else { retval = __slowexp(x); goto ret; }
   }
+ ret:
+  libc_feupdateenv (&env);
+  return retval;
 }
 #ifndef __ieee754_exp
 strong_alias (__ieee754_exp, __exp_finite)
diff --git a/sysdeps/x86_64/fpu/libm-test-ulps b/sysdeps/x86_64/fpu/libm-test-ulps
index dac90ba..74df77c 100644
--- a/sysdeps/x86_64/fpu/libm-test-ulps
+++ b/sysdeps/x86_64/fpu/libm-test-ulps
@@ -512,6 +512,41 @@ ifloat: 2
 ildouble: 8
 ldouble: 8
 
+# exp_downward
+Test "exp_downward (1) == e":
+ildouble: 1
+ldouble: 1
+Test "exp_downward (2) == e^2":
+float: 1
+ifloat: 1
+ildouble: 2
+ldouble: 2
+Test "exp_downward (3) == e^3":
+float: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+# exp_towardzero
+Test "exp_towardzero (1) == e":
+ildouble: 1
+ldouble: 1
+Test "exp_towardzero (2) == e^2":
+float: 1
+ifloat: 1
+ildouble: 2
+ldouble: 2
+Test "exp_towardzero (3) == e^3":
+float: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+
+# exp_upward
+Test "exp_upward (1) == e":
+float: 1
+ifloat: 1
+
 # expm1
 Test "expm1 (0.75) == 1.11700001661267466854536981983709561":
 double: 1
@@ -1275,6 +1310,22 @@ ifloat: 2
 ildouble: 8
 ldouble: 8
 
+Function: "exp_downward":
+float: 1
+ifloat: 1
+ildouble: 2
+ldouble: 2
+
+Function: "exp_towardzero":
+float: 1
+ifloat: 1
+ildouble: 2
+ldouble: 2
+
+Function: "exp_upward":
+float: 1
+ifloat: 1
+
 Function: "expm1":
 double: 1
 float: 1

-----------------------------------------------------------------------

Summary of changes:
 ChangeLog                         |   14 +++++
 math/libm-test.inc                |  112 +++++++++++++++++++++++++++++++++++++
 sysdeps/i386/fpu/libm-test-ulps   |   67 ++++++++++++++++++++++
 sysdeps/ieee754/dbl-64/e_exp.c    |   38 ++++++++-----
 sysdeps/x86_64/fpu/libm-test-ulps |   51 +++++++++++++++++
 5 files changed, 268 insertions(+), 14 deletions(-)


hooks/post-receive
-- 
GNU C Library master sources


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]