This is the mail archive of the mailing list for the glibc project.

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Fix atan2 spurious exceptions (bug 11451)

Bug 11451 reports atan2 raising spurious overflow exceptions for large
input on x86_64.  (It also raises spurious invalid exceptions for the
same input, not mentioned in that bug report.)  The code already
scales the inputs if very small, and already has handling for the case
where the inputs are very different in magnitude; I propose this patch
adding scaling for large inputs.

Tested x86_64 and x86; no ulps changes needed.

2012-03-19  Joseph Myers  <>

	[BZ #11451]
	* sysdeps/ieee754/dbl-64/e_atan2.c (__ieee754_atan2): Scale large
	x and y.
	* math/ (atan2_test): Add another test.

diff --git a/math/ b/math/
index 5638b76..817864a 100644
--- a/math/
+++ b/math/
@@ -949,6 +949,8 @@ atan2_test (void)
   TEST_ff_f (atan2, minus_infty, minus_infty, -M_PI_34l);
   TEST_ff_f (atan2, nan_value, nan_value, nan_value);
+  TEST_ff_f (atan2, max_value, max_value, M_PI_4l);
   TEST_ff_f (atan2, 0.75L, 1, 0.643501108793284386802809228717322638L);
   TEST_ff_f (atan2, -0.75L, 1.0L, -0.643501108793284386802809228717322638L);
   TEST_ff_f (atan2, 0.75L, -1.0L, 2.49809154479650885165983415456218025L);
diff --git a/sysdeps/ieee754/dbl-64/e_atan2.c b/sysdeps/ieee754/dbl-64/e_atan2.c
index dcef55f..497afca 100644
--- a/sysdeps/ieee754/dbl-64/e_atan2.c
+++ b/sysdeps/ieee754/dbl-64/e_atan2.c
@@ -1,7 +1,7 @@
  * IBM Accurate Mathematical Library
  * written by International Business Machines Corp.
- * Copyright (C) 2001, 2011 Free Software Foundation
+ * Copyright (C) 2001-2012 Free Software Foundation
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU Lesser General Public License as published by
@@ -153,6 +153,13 @@ __ieee754_atan2(double y,double x) {
   /* if either x or y is extremely close to zero, scale abs(x), abs(y). */
   if (ax<twom500.d || ay<twom500.d) { ax*=two500.d;  ay*=two500.d; }
+  /* Likewise for large x and y.  */
+  if (ax > two500.d || ay > two500.d)
+    {
+      ax *= twom500.d;
+      ay *= twom500.d;
+    }
   /* x,y which are neither special nor extreme */
   if (ay<ax) {

Joseph S. Myers

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]