]> git.ipfire.org Git - thirdparty/glibc.git/commitdiff
Fix missing exp2 overflow exception (bug 13871).
authorJoseph Myers <joseph@codesourcery.com>
Wed, 21 Mar 2012 12:17:26 +0000 (12:17 +0000)
committerJoseph Myers <joseph@codesourcery.com>
Wed, 21 Mar 2012 12:17:26 +0000 (12:17 +0000)
ChangeLog
NEWS
math/libm-test.inc
math/w_exp2.c
math/w_exp2f.c
math/w_exp2l.c

index d548878793b7b259b1ac8eebe5d41142858e2fc8..c10024a541a9c64bf130840be336cf36379409f3 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,4 +1,14 @@
-2012-03-20  Joseph Myers  <joseph@codesourcery.com>
+2012-03-21  Joseph Myers  <joseph@codesourcery.com>
+
+       [BZ #13871]
+       * math/w_exp2.c: Do not include <float.h>.
+       (o_threshold, u_threshold): Remove.
+       (__exp2): Calculate result before checking finiteness and calling
+       __kernel_standard.
+       * math/w_exp2f.c: Likewise.
+       * math/w_exp2l.c: Likewise.
+       * math/libm-test.inc (exp2_test): Require overflow exception for
+       1e6 input.
 
        [BZ #3866]
        * sysdeps/i386/fpu/e_pow.S (__ieee754_pow): Test for y outside the
diff --git a/NEWS b/NEWS
index df8e1f03a6b47446990ca93dccf85939e5b446f2..a8a3e5716cd677bc9317e327b10bd2c5e253b48b 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -16,7 +16,7 @@ Version 2.16
   13526, 13527, 13528, 13529, 13530, 13531, 13532, 13533, 13547, 13551,
   13552, 13553, 13555, 13559, 13566, 13583, 13618, 13637, 13656, 13658,
   13673, 13695, 13704, 13706, 13726, 13738, 13786, 13792, 13806, 13840,
-  13841, 13844, 13846, 13851, 13852, 13854
+  13841, 13844, 13846, 13851, 13852, 13854, 13871
 
 * ISO C11 support:
 
index 64d12a5786c3643b4851bc66633a444a3552b2c0..afc6f55d7b0d140d8fcb42123dbba73e51f7bf7a 100644 (file)
@@ -3108,8 +3108,7 @@ exp2_test (void)
 
   TEST_f_f (exp2, 10, 1024);
   TEST_f_f (exp2, -1, 0.5);
-  /* Bug 13871: OVERFLOW exception may be missing.  */
-  TEST_f_f (exp2, 1e6, plus_infty, OVERFLOW_EXCEPTION_OK);
+  TEST_f_f (exp2, 1e6, plus_infty, OVERFLOW_EXCEPTION);
   TEST_f_f (exp2, -1e6, 0);
   TEST_f_f (exp2, 0.75L, 1.68179283050742908606225095246642979L);
 
index 7a3b0afb74d224206f1b1ce6cfeab6cc64dc8168..b5d8e25702340f24d2b9f919c5457291db320c20 100644 (file)
@@ -2,23 +2,19 @@
  * wrapper exp2(x)
  */
 
-#include <float.h>
 #include <math.h>
 #include <math_private.h>
 
-static const double o_threshold = (double) DBL_MAX_EXP;
-static const double u_threshold = (double) (DBL_MIN_EXP - DBL_MANT_DIG - 1);
-
 double
 __exp2 (double x)
 {
-  if (__builtin_expect (islessequal (x, u_threshold)
-                       || isgreater (x, o_threshold), 0)
-      && _LIB_VERSION != _IEEE_ && __finite (x))
+  double z = __ieee754_exp2 (x);
+  if (__builtin_expect (!__finite (z), 0)
+      && __finite (x) && _LIB_VERSION != _IEEE_)
     /* exp2 overflow: 44, exp2 underflow: 45 */
-    return __kernel_standard (x, x, 44 + (x <= o_threshold));
+    return __kernel_standard (x, x, 44 + !!__signbit (x));
 
-  return __ieee754_exp2 (x);
+  return z;
 }
 weak_alias (__exp2, exp2)
 #ifdef NO_LONG_DOUBLE
index c4e9e941640be66ba32a726d1f3d1f5a6fcc58f8..7c277ef39080bd949658edb0adea984fd303ffda 100644 (file)
@@ -2,22 +2,18 @@
  * wrapper exp2f(x)
  */
 
-#include <float.h>
 #include <math.h>
 #include <math_private.h>
 
-static const float o_threshold = (float) FLT_MAX_EXP;
-static const float u_threshold = (float) (FLT_MIN_EXP - FLT_MANT_DIG - 1);
-
 float
 __exp2f (float x)
 {
-  if (__builtin_expect (islessequal (x, u_threshold)
-                       || isgreater (x, o_threshold), 0)
-      && _LIB_VERSION != _IEEE_ && __finitef (x))
+  float z = __ieee754_exp2f (x);
+  if (__builtin_expect (!__finitef (z), 0)
+      && __finitef (x) && _LIB_VERSION != _IEEE_)
     /* exp2 overflow: 144, exp2 underflow: 145 */
-    return __kernel_standard_f (x, x, 144 + (x <= o_threshold));
+    return __kernel_standard_f (x, x, 144 + !!__signbitf (x));
 
-  return __ieee754_exp2f (x);
+  return z;
 }
 weak_alias (__exp2f, exp2f)
index 442a637347e19685d8ace82682a5e97622df10ae..f05a8fe6d6dae13885df7e3fe70d98f5cd5bbfe6 100644 (file)
@@ -2,23 +2,18 @@
  * wrapper exp2l(x)
  */
 
-#include <float.h>
 #include <math.h>
 #include <math_private.h>
 
-static const long double o_threshold = (long double) LDBL_MAX_EXP;
-static const long double u_threshold
-  = (long double) (LDBL_MIN_EXP - LDBL_MANT_DIG - 1);
-
 long double
 __exp2l (long double x)
 {
-  if (__builtin_expect (islessequal (x, u_threshold)
-                       || isgreater (x, o_threshold), 0)
-      && _LIB_VERSION != _IEEE_ && __finitel (x))
+  long double z = __ieee754_exp2l (x);
+  if (__builtin_expect (!__finitel (z), 0)
+      && __finitel (x) && _LIB_VERSION != _IEEE_)
     /* exp2 overflow: 244, exp2 underflow: 245 */
-    return __kernel_standard (x, x, 244 + (x <= o_threshold));
+    return __kernel_standard (x, x, 244 + !!__signbitl (x));
 
-  return __ieee754_exp2l (x);
+  return z;
 }
 weak_alias (__exp2l, exp2l)