diff options
author | Joseph Myers <joseph@codesourcery.com> | 2012-03-21 12:17:26 +0000 |
---|---|---|
committer | Joseph Myers <joseph@codesourcery.com> | 2012-03-21 12:17:26 +0000 |
commit | 0cb7efc517a293417880f02e2991483b7ce1e3f9 (patch) | |
tree | 6c0c2e224abce394aa9713bf8de43d4ff8012bdb | |
parent | 2460d3aa21f04cdf28497683bd3e29183189f779 (diff) | |
download | glibc-0cb7efc517a293417880f02e2991483b7ce1e3f9.tar.gz glibc-0cb7efc517a293417880f02e2991483b7ce1e3f9.tar.xz glibc-0cb7efc517a293417880f02e2991483b7ce1e3f9.zip |
Fix missing exp2 overflow exception (bug 13871).
-rw-r--r-- | ChangeLog | 12 | ||||
-rw-r--r-- | NEWS | 2 | ||||
-rw-r--r-- | math/libm-test.inc | 3 | ||||
-rw-r--r-- | math/w_exp2.c | 14 | ||||
-rw-r--r-- | math/w_exp2f.c | 14 | ||||
-rw-r--r-- | math/w_exp2l.c | 15 |
6 files changed, 28 insertions, 32 deletions
diff --git a/ChangeLog b/ChangeLog index d548878793..c10024a541 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 df8e1f03a6..a8a3e5716c 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 64d12a5786..afc6f55d7b 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 7a3b0afb74..b5d8e25702 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 c4e9e94164..7c277ef390 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 442a637347..f05a8fe6d6 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) |