]> git.ipfire.org Git - thirdparty/glibc.git/commitdiff
Fix exp10 spurious overflows (bug 13924).
authorJoseph Myers <joseph@codesourcery.com>
Mon, 30 Apr 2012 09:37:01 +0000 (09:37 +0000)
committerJoseph Myers <joseph@codesourcery.com>
Mon, 30 Apr 2012 09:37:01 +0000 (09:37 +0000)
ChangeLog
NEWS
math/e_exp10.c
math/e_exp10f.c
math/e_exp10l.c
math/libm-test.inc

index a13bcec7cc959c68936b240dfa138a2fe28d7410..7a65e6c5b5b1eebd877f031f1579a5a99641e278 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,18 @@
+2012-04-30  Joseph Myers  <joseph@codesourcery.com>
+
+       [BZ #13884]
+       [BZ #13924]
+       * math/e_exp10.c: Include <float.h>.
+       (__ieee754_exp10): Handle underflow here rather than multiplying
+       large negative argument by M_LN10.
+       * math/e_exp10f.c (__ieee754_exp10f): Call __ieee754_exp instead
+       of __ieee754_expf.
+       * math/e_exp10l.c: Include <float.h>.
+       (__ieee754_exp10l): Handle underflow here rather than multiplying
+       large negative argument by M_LN10l.
+       * math/libm-test.inc (exp10_test): Add another test.  Do not allow
+       spurious overflow exception on underflow.
+
 2012-04-29  Marek Polacek  <polacek@redhat.com>
 
        * misc/sys/cdefs.h (__attribute_artificial__): New macro.
diff --git a/NEWS b/NEWS
index c1d051de8518323c9697e14c7019ca01268f42ef..da9174eff8079c0b443b1272ff90f3ff060ad163 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -21,8 +21,8 @@ Version 2.16
   13739, 13758, 13760, 13761, 13786, 13792, 13806, 13824, 13840, 13841,
   13844, 13846, 13851, 13852, 13854, 13871, 13872, 13873, 13879, 13883,
   13886, 13892, 13895, 13908, 13910, 13911, 13912, 13913, 13915, 13916,
-  13917, 13918, 13919, 13920, 13921, 13926, 13927, 13928, 13938, 13941,
-  13963, 13967, 13970, 13973, 14027, 14033
+  13917, 13918, 13919, 13920, 13921, 13924, 13926, 13927, 13928, 13938,
+  13941, 13963, 13967, 13970, 13973, 14027, 14033
 
 * ISO C11 support:
 
index 75185836b898eb8ecf5f92b00aaa1b6a90ad0fa8..ce319fdcd2c54476a765c272d5b7f35c8862c47c 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 1998, 2011 Free Software Foundation, Inc.
+/* Copyright (C) 1998-2012 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998.
 
 
 #include <math.h>
 #include <math_private.h>
-
+#include <float.h>
 
 double
 __ieee754_exp10 (double arg)
 {
-  /* This is a very stupid and inprecise implementation.  It'll get
-     replaced sometime (soon?).  */
-  return __ieee754_exp (M_LN10 * arg);
+  if (__finite (arg) && arg < DBL_MIN_10_EXP - DBL_DIG - 10)
+    return DBL_MIN * DBL_MIN;
+  else
+    /* This is a very stupid and inprecise implementation.  It'll get
+       replaced sometime (soon?).  */
+    return __ieee754_exp (M_LN10 * arg);
 }
 strong_alias (__ieee754_exp10, __exp10_finite)
index 7b940053fb27b3cfa4830b18bcf082ad509b386d..582824fcf5da5262659b309c5fc97cc820ed64a7 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 1998, 2011 Free Software Foundation, Inc.
+/* Copyright (C) 1998-2012 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998.
 
 float
 __ieee754_exp10f (float arg)
 {
-  /* This is a very stupid and inprecise implementation.  It'll get
-     replaced sometime (soon?).  */
-  return __ieee754_expf (M_LN10 * arg);
+  /* The argument to exp needs to be calculated in enough precision
+     that the fractional part has as much precision as float, in
+     addition to the bits in the integer part; using double ensures
+     this.  */
+  return __ieee754_exp (M_LN10 * arg);
 }
 strong_alias (__ieee754_exp10f, __exp10f_finite)
index e3dad0a1833af1f96ba714233b14742152040ccc..d57c8cfa4f859e9c9d35968f75f80c83d01e501d 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 1998, 2011 Free Software Foundation, Inc.
+/* Copyright (C) 1998-2012 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998.
 
 
 #include <math.h>
 #include <math_private.h>
-
+#include <float.h>
 
 long double
 __ieee754_exp10l (long double arg)
 {
-  /* This is a very stupid and inprecise implementation.  It'll get
-     replaced sometime (soon?).  */
-  return __ieee754_expl (M_LN10l * arg);
+  if (__finitel (arg) && arg < LDBL_MIN_10_EXP - LDBL_DIG - 10)
+    return LDBL_MIN * LDBL_MIN;
+  else
+    /* This is a very stupid and inprecise implementation.  It'll get
+       replaced sometime (soon?).  */
+    return __ieee754_expl (M_LN10l * arg);
 }
 strong_alias (__ieee754_exp10l, __exp10l_finite)
index 1b5d1c7e42009075e7de012cc2333ae4e8c915f0..cd627cd829405bac41c46088b5d19cff1481ed9a 100644 (file)
@@ -3196,12 +3196,14 @@ exp10_test (void)
   TEST_f_f (exp10, nan_value, nan_value);
   TEST_f_f (exp10, 3, 1000);
   TEST_f_f (exp10, -1, 0.1L);
+#ifdef TEST_FLOAT /* Bug 13884: inaccurate results except for float.  */
+  TEST_f_f (exp10, 36, 1.0e36L);
+#endif
   TEST_f_f (exp10, 1e6, plus_infty, OVERFLOW_EXCEPTION);
   TEST_f_f (exp10, -1e6, 0);
 #ifndef TEST_LDOUBLE /* Bug 13914: spurious exceptions.  */
   TEST_f_f (exp10, max_value, plus_infty, OVERFLOW_EXCEPTION);
-  /* Bug 13924: spurious OVERFLOW exception may be present.  */
-  TEST_f_f (exp10, -max_value, 0, OVERFLOW_EXCEPTION_OK);
+  TEST_f_f (exp10, -max_value, 0);
 #endif
   TEST_f_f (exp10, 0.75L, 5.62341325190349080394951039776481231L);