about summary refs log tree commit diff
diff options
context:
space:
mode:
authorJoseph Myers <joseph@codesourcery.com>2012-04-09 09:43:18 +0000
committerJoseph Myers <joseph@codesourcery.com>2012-04-09 09:43:18 +0000
commitd7dd94539899466a9a4e38c61ab846ffcb314dad (patch)
tree30a319648bb4afe4e4296d2e77cb7bbf8084893d
parentc483f6b4a4277bc209820efc1ae35d976af57b4e (diff)
downloadglibc-d7dd94539899466a9a4e38c61ab846ffcb314dad.tar.gz
glibc-d7dd94539899466a9a4e38c61ab846ffcb314dad.tar.xz
glibc-d7dd94539899466a9a4e38c61ab846ffcb314dad.zip
Fix missing overflow exceptions from pow (bug 13873).
-rw-r--r--ChangeLog8
-rw-r--r--NEWS6
-rw-r--r--math/libm-test.inc15
-rw-r--r--sysdeps/ieee754/dbl-64/e_pow.c5
4 files changed, 19 insertions, 15 deletions
diff --git a/ChangeLog b/ChangeLog
index 6c4bd0732a..75a5ca8137 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,13 @@
 2012-04-09  Joseph Myers  <joseph@codesourcery.com>
 
+	[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 5bd167709b..a17f611ff3 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 b9ff9f3ad2..0533483749 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 26ffaaddc6..6c41af93ba 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;