Fix exp10 spurious overflows (bug 13924).

This commit is contained in:
Joseph Myers 2012-04-30 09:37:01 +00:00
parent 6c1ff08cf8
commit 9568c0c225
6 changed files with 43 additions and 18 deletions

View File

@ -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> 2012-04-29 Marek Polacek <polacek@redhat.com>
* misc/sys/cdefs.h (__attribute_artificial__): New macro. * misc/sys/cdefs.h (__attribute_artificial__): New macro.

4
NEWS
View File

@ -21,8 +21,8 @@ Version 2.16
13739, 13758, 13760, 13761, 13786, 13792, 13806, 13824, 13840, 13841, 13739, 13758, 13760, 13761, 13786, 13792, 13806, 13824, 13840, 13841,
13844, 13846, 13851, 13852, 13854, 13871, 13872, 13873, 13879, 13883, 13844, 13846, 13851, 13852, 13854, 13871, 13872, 13873, 13879, 13883,
13886, 13892, 13895, 13908, 13910, 13911, 13912, 13913, 13915, 13916, 13886, 13892, 13895, 13908, 13910, 13911, 13912, 13913, 13915, 13916,
13917, 13918, 13919, 13920, 13921, 13926, 13927, 13928, 13938, 13941, 13917, 13918, 13919, 13920, 13921, 13924, 13926, 13927, 13928, 13938,
13963, 13967, 13970, 13973, 14027, 14033 13941, 13963, 13967, 13970, 13973, 14027, 14033
* ISO C11 support: * ISO C11 support:

View 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. This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998. Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998.
@ -18,13 +18,16 @@
#include <math.h> #include <math.h>
#include <math_private.h> #include <math_private.h>
#include <float.h>
double double
__ieee754_exp10 (double arg) __ieee754_exp10 (double arg)
{ {
/* This is a very stupid and inprecise implementation. It'll get if (__finite (arg) && arg < DBL_MIN_10_EXP - DBL_DIG - 10)
replaced sometime (soon?). */ return DBL_MIN * DBL_MIN;
return __ieee754_exp (M_LN10 * arg); 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) strong_alias (__ieee754_exp10, __exp10_finite)

View 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. This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998. Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998.
@ -23,8 +23,10 @@
float float
__ieee754_exp10f (float arg) __ieee754_exp10f (float arg)
{ {
/* This is a very stupid and inprecise implementation. It'll get /* The argument to exp needs to be calculated in enough precision
replaced sometime (soon?). */ that the fractional part has as much precision as float, in
return __ieee754_expf (M_LN10 * arg); addition to the bits in the integer part; using double ensures
this. */
return __ieee754_exp (M_LN10 * arg);
} }
strong_alias (__ieee754_exp10f, __exp10f_finite) strong_alias (__ieee754_exp10f, __exp10f_finite)

View 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. This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998. Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998.
@ -18,13 +18,16 @@
#include <math.h> #include <math.h>
#include <math_private.h> #include <math_private.h>
#include <float.h>
long double long double
__ieee754_exp10l (long double arg) __ieee754_exp10l (long double arg)
{ {
/* This is a very stupid and inprecise implementation. It'll get if (__finitel (arg) && arg < LDBL_MIN_10_EXP - LDBL_DIG - 10)
replaced sometime (soon?). */ return LDBL_MIN * LDBL_MIN;
return __ieee754_expl (M_LN10l * arg); 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) strong_alias (__ieee754_exp10l, __exp10l_finite)

View File

@ -3196,12 +3196,14 @@ exp10_test (void)
TEST_f_f (exp10, nan_value, nan_value); TEST_f_f (exp10, nan_value, nan_value);
TEST_f_f (exp10, 3, 1000); TEST_f_f (exp10, 3, 1000);
TEST_f_f (exp10, -1, 0.1L); 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, plus_infty, OVERFLOW_EXCEPTION);
TEST_f_f (exp10, -1e6, 0); TEST_f_f (exp10, -1e6, 0);
#ifndef TEST_LDOUBLE /* Bug 13914: spurious exceptions. */ #ifndef TEST_LDOUBLE /* Bug 13914: spurious exceptions. */
TEST_f_f (exp10, max_value, plus_infty, OVERFLOW_EXCEPTION); 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);
TEST_f_f (exp10, -max_value, 0, OVERFLOW_EXCEPTION_OK);
#endif #endif
TEST_f_f (exp10, 0.75L, 5.62341325190349080394951039776481231L); TEST_f_f (exp10, 0.75L, 5.62341325190349080394951039776481231L);