From d7dd94539899466a9a4e38c61ab846ffcb314dad Mon Sep 17 00:00:00 2001 From: Joseph Myers Date: Mon, 9 Apr 2012 09:43:18 +0000 Subject: [PATCH] Fix missing overflow exceptions from pow (bug 13873). --- ChangeLog | 8 ++++++++ NEWS | 6 +++--- math/libm-test.inc | 15 +++++---------- sysdeps/ieee754/dbl-64/e_pow.c | 5 +++-- 4 files changed, 19 insertions(+), 15 deletions(-) diff --git a/ChangeLog b/ChangeLog index 6c4bd07..75a5ca8 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,13 @@ 2012-04-09 Joseph Myers + [BZ #13873] + * sysdeps/ieee754/dbl-64/e_pow.c (huge, tiny): New variables. + (__ieee754_pow): Generate overflow and underflow using huge*huge + and tiny*tiny rather than just returning constant infinity or zero + for large exponents. + * math/libm-test.inc (pow_test): Require overflow exceptions for + applicable cases of large exponents. + [BZ #706] * sysdeps/i386/fpu/e_pow.S (p10): New object. (__ieee754_pow): Use iterative multiplication algorithm only for diff --git a/NEWS b/NEWS index 5bd1677..a17f611 100644 --- a/NEWS +++ b/NEWS @@ -18,9 +18,9 @@ Version 2.16 13533, 13547, 13551, 13552, 13553, 13555, 13559, 13566, 13583, 13592, 13618, 13637, 13656, 13658, 13673, 13691, 13695, 13704, 13705, 13706, 13726, 13738, 13760, 13761, 13786, 13792, 13806, 13824, 13840, 13841, - 13844, 13846, 13851, 13852, 13854, 13871, 13879, 13883, 13892, 13895, - 13908, 13910, 13911, 13912, 13913, 13915, 13916, 13917, 13918, 13919, - 13920, 13921, 13926, 13928, 13938 + 13844, 13846, 13851, 13852, 13854, 13871, 13873, 13879, 13883, 13892, + 13895, 13908, 13910, 13911, 13912, 13913, 13915, 13916, 13917, 13918, + 13919, 13920, 13921, 13926, 13928, 13938 * ISO C11 support: diff --git a/math/libm-test.inc b/math/libm-test.inc index b9ff9f3..0533483 100644 --- a/math/libm-test.inc +++ b/math/libm-test.inc @@ -5621,8 +5621,7 @@ pow_test (void) TEST_ff_f (pow, 0x1p72L, 0x1p72L, plus_infty, OVERFLOW_EXCEPTION); TEST_ff_f (pow, 10, -0x1p72L, 0); - /* Bug 13873: OVERFLOW exception may be missing. */ - TEST_ff_f (pow, max_value, max_value, plus_infty, OVERFLOW_EXCEPTION_OK); + TEST_ff_f (pow, max_value, max_value, plus_infty, OVERFLOW_EXCEPTION); /* Bug 13872: spurious OVERFLOW exception may be present. */ TEST_ff_f (pow, 10, -max_value, 0, OVERFLOW_EXCEPTION_OK); @@ -5908,8 +5907,7 @@ pow_test (void) TEST_ff_f (pow, -2.0, 0x1.ffffffffffffffffffffffffffffp+113L, plus_infty, OVERFLOW_EXCEPTION); # endif #endif - /* Bug 13873: OVERFLOW exception may be missing. */ - TEST_ff_f (pow, -2.0, max_value, plus_infty, OVERFLOW_EXCEPTION_OK); + TEST_ff_f (pow, -2.0, max_value, plus_infty, OVERFLOW_EXCEPTION); TEST_ff_f (pow, -max_value, 0.5, nan_value, INVALID_EXCEPTION); TEST_ff_f (pow, -max_value, 1.5, nan_value, INVALID_EXCEPTION); @@ -5962,8 +5960,7 @@ pow_test (void) TEST_ff_f (pow, -max_value, 0x1.ffffffffffffffffffffffffffffp+113L, plus_infty, OVERFLOW_EXCEPTION); # endif #endif - /* Bug 13873: OVERFLOW exception may be missing. */ - TEST_ff_f (pow, -max_value, max_value, plus_infty, OVERFLOW_EXCEPTION_OK); + TEST_ff_f (pow, -max_value, max_value, plus_infty, OVERFLOW_EXCEPTION); TEST_ff_f (pow, -0.5, 126, 0x1p-126); TEST_ff_f (pow, -0.5, 127, -0x1p-127); @@ -5990,8 +5987,7 @@ pow_test (void) TEST_ff_f (pow, -0.5, -0x1.ffffffffffffffffffffffffffffp+113L, plus_infty, OVERFLOW_EXCEPTION); # endif #endif - /* Bug 13873: OVERFLOW exception may be missing. */ - TEST_ff_f (pow, -0.5, -max_value, plus_infty, OVERFLOW_EXCEPTION_OK); + TEST_ff_f (pow, -0.5, -max_value, plus_infty, OVERFLOW_EXCEPTION); TEST_ff_f (pow, -0.5, 0xffffff, minus_zero); TEST_ff_f (pow, -0.5, 0x1fffffe, plus_zero); @@ -6044,8 +6040,7 @@ pow_test (void) TEST_ff_f (pow, -min_value, -0x1.ffffffffffffffffffffffffffffp+113L, plus_infty, OVERFLOW_EXCEPTION); # endif #endif - /* Bug 13873: OVERFLOW exception may be missing. */ - TEST_ff_f (pow, -min_value, -max_value, plus_infty, OVERFLOW_EXCEPTION_OK); + TEST_ff_f (pow, -min_value, -max_value, plus_infty, OVERFLOW_EXCEPTION); TEST_ff_f (pow, -min_value, 0xffffff, minus_zero); TEST_ff_f (pow, -min_value, 0x1fffffe, plus_zero); diff --git a/sysdeps/ieee754/dbl-64/e_pow.c b/sysdeps/ieee754/dbl-64/e_pow.c index 26ffaad..6c41af9 100644 --- a/sysdeps/ieee754/dbl-64/e_pow.c +++ b/sysdeps/ieee754/dbl-64/e_pow.c @@ -47,6 +47,7 @@ # define SECTION #endif +static const double huge = 1.0e300, tiny = 1.0e-300; double __exp1(double x, double xx, double error); static double log1(double x, double *delta, double *error); @@ -156,8 +157,8 @@ __ieee754_pow(double x, double y) { if (qy > 0x45f00000 && qy < 0x7ff00000) { if (x == 1.0) return 1.0; - if (y>0) return (x>1.0)?INF.x:0; - if (y<0) return (x<1.0)?INF.x:0; + if (y>0) return (x>1.0)?huge*huge:tiny*tiny; + if (y<0) return (x<1.0)?huge*huge:tiny*tiny; } if (x == 1.0) return 1.0; -- 2.7.4