Fix missing exp2 overflow exception (bug 13871).

This commit is contained in:
Joseph Myers 2012-03-21 12:17:26 +00:00
parent 2460d3aa21
commit 0cb7efc517
6 changed files with 28 additions and 32 deletions

View file

@ -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

2
NEWS
View file

@ -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:

View 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);

View 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

View 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)

View 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)