aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoseph Myers <joseph@codesourcery.com>2012-03-21 12:17:26 +0000
committerJoseph Myers <joseph@codesourcery.com>2012-03-21 12:17:26 +0000
commit0cb7efc517a293417880f02e2991483b7ce1e3f9 (patch)
tree6c0c2e224abce394aa9713bf8de43d4ff8012bdb
parent2460d3aa21f04cdf28497683bd3e29183189f779 (diff)
downloadglibc-0cb7efc517a293417880f02e2991483b7ce1e3f9.zip
glibc-0cb7efc517a293417880f02e2991483b7ce1e3f9.tar.gz
glibc-0cb7efc517a293417880f02e2991483b7ce1e3f9.tar.bz2
Fix missing exp2 overflow exception (bug 13871).
-rw-r--r--ChangeLog12
-rw-r--r--NEWS2
-rw-r--r--math/libm-test.inc3
-rw-r--r--math/w_exp2.c14
-rw-r--r--math/w_exp2f.c14
-rw-r--r--math/w_exp2l.c15
6 files changed, 28 insertions, 32 deletions
diff --git a/ChangeLog b/ChangeLog
index d548878..c10024a 100644
--- 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 df8e1f0..a8a3e57 100644
--- 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:
diff --git a/math/libm-test.inc b/math/libm-test.inc
index 64d12a5..afc6f55 100644
--- a/math/libm-test.inc
+++ b/math/libm-test.inc
@@ -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);
diff --git a/math/w_exp2.c b/math/w_exp2.c
index 7a3b0af..b5d8e25 100644
--- a/math/w_exp2.c
+++ b/math/w_exp2.c
@@ -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
diff --git a/math/w_exp2f.c b/math/w_exp2f.c
index c4e9e94..7c277ef 100644
--- a/math/w_exp2f.c
+++ b/math/w_exp2f.c
@@ -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)
diff --git a/math/w_exp2l.c b/math/w_exp2l.c
index 442a637..f05a8fe 100644
--- a/math/w_exp2l.c
+++ b/math/w_exp2l.c
@@ -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)