This is the mail archive of the libc-alpha@sourceware.org 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]

Re: [PATCH] Update sparc ULPs.


From: "Joseph S. Myers" <joseph@codesourcery.com>
Date: Mon, 19 Nov 2012 16:29:28 +0000

> On Sun, 18 Nov 2012, David Miller wrote:
> 
>> But I'll try to take care of both boundary conditions while I'm here.
>> This patch below is what I currently have, although I'm not so sure
>> about the boundary points I picked.
>> 
>> I know that the limiting factor is the multiplication of the largest
>> terms that go into the polynomial computation.
> 
> For small arguments what's relevant is x - x^3/3 being indistinguishable 
> from x (i.e. x^3/3 being less than 0.5ulp of x).  For large arguments it's 
> pi/2 - 1/x being indistinguishable from pi/2.  So the cutoffs you chose 
> seem reasonable in both cases.

Here is the final version, which I committed.

I tried to wrap my brain around the IBM extended 128-bit long double
format, and failed. :-) Someone more versed in it should find it quite
easy to cons up the ldbl-128ibm/atanl.c version of this fix so that
the powerpc long double testsuite failures are all cured.

I also found it surprising that we lack a ldbl-96 specific version of
atanl().

Anyways, with this, sparc is back down to zero testsuite failures.

====================
Fix spurious underflows in ldbl-128 atan implementation.

	With help from Joseph Myers.
	* sysdeps/ieee754/ldbl-128/s_atanl.c (__atanl): Handle tiny and
	very large arguments properly.
	* math/libm-test.inc (atan_test): New tests.
	(atan2_test): New tests.
	* sysdeps/sparc/fpu/libm-test-ulps: Update.
	* sysdeps/x86_64/fpu/libm-test-ulps: Update.
---
 ChangeLog                          | 10 ++++++++++
 math/libm-test.inc                 |  5 +++++
 sysdeps/ieee754/ldbl-128/s_atanl.c | 17 +++++++++++++++++
 sysdeps/sparc/fpu/libm-test-ulps   |  3 +++
 sysdeps/x86_64/fpu/libm-test-ulps  |  3 +++
 5 files changed, 38 insertions(+)

diff --git a/ChangeLog b/ChangeLog
index 5ab7adb..5406559 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,13 @@
+2012-11-19  David S. Miller  <davem@davemloft.net>
+
+	With help from Joseph Myers.
+	* sysdeps/ieee754/ldbl-128/s_atanl.c (__atanl): Handle tiny and
+	very large arguments properly.
+	* math/libm-test.inc (atan_test): New tests.
+	(atan2_test): New tests.
+	* sysdeps/sparc/fpu/libm-test-ulps: Update.
+	* sysdeps/x86_64/fpu/libm-test-ulps: Update.
+
 2012-11-19  Joseph Myers  <joseph@codesourcery.com>
 
 	* conform/data/errno.h-data [POSIX] (EADDRINUSE): Do not expect.
diff --git a/math/libm-test.inc b/math/libm-test.inc
index 0b254e1..2a60557 100644
--- a/math/libm-test.inc
+++ b/math/libm-test.inc
@@ -1187,6 +1187,8 @@ atan_test (void)
   TEST_f_f (atan, plus_infty, M_PI_2l);
   TEST_f_f (atan, minus_infty, -M_PI_2l);
   TEST_f_f (atan, nan_value, nan_value);
+  TEST_f_f (atan, max_value, M_PI_2l);
+  TEST_f_f (atan, -max_value, -M_PI_2l);
 
   TEST_f_f (atan, 1, M_PI_4l);
   TEST_f_f (atan, -1, -M_PI_4l);
@@ -1295,6 +1297,9 @@ atan2_test (void)
 
   TEST_ff_f (atan2, max_value, max_value, M_PI_4l);
 
+  TEST_ff_f (atan2, max_value, min_value, M_PI_2l);
+  TEST_ff_f (atan2, -max_value, -min_value, -M_PI_2l);
+
   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/ldbl-128/s_atanl.c b/sysdeps/ieee754/ldbl-128/s_atanl.c
index 0138e79..adac0a7 100644
--- a/sysdeps/ieee754/ldbl-128/s_atanl.c
+++ b/sysdeps/ieee754/ldbl-128/s_atanl.c
@@ -167,6 +167,7 @@ static const long double
   q4 = 2.173623741810414221251136181221172551416E1L;
   /* q5 = 1.000000000000000000000000000000000000000E0 */
 
+static const long double huge = 1.0e4930L;
 
 long double
 __atanl (long double x)
@@ -197,6 +198,22 @@ __atanl (long double x)
 	return atantbl[83];
     }
 
+  if (k <= 0x3fc50000) /* |x| < 2**-58 */
+    {
+      /* Raise inexact. */
+      if (huge + x > 0.0)
+	return x;
+    }
+
+  if (k >= 0x40720000) /* |x| > 2**115 */
+    {
+      /* Saturate result to {-,+}pi/2 */
+      if (sign)
+	return -atantbl[83];
+      else
+	return atantbl[83];
+    }
+
   if (sign)
       x = -x;
 
diff --git a/sysdeps/sparc/fpu/libm-test-ulps b/sysdeps/sparc/fpu/libm-test-ulps
index ec0ad66..432e011 100644
--- a/sysdeps/sparc/fpu/libm-test-ulps
+++ b/sysdeps/sparc/fpu/libm-test-ulps
@@ -102,6 +102,9 @@ float: 1
 ifloat: 1
 ildouble: 1
 ldouble: 1
+Test "atan2 (-max_value, -min_value) == -pi/2":
+float: 1
+ifloat: 1
 Test "atan2 (0.75, -1.0) == 2.49809154479650885165983415456218025":
 float: 1
 ifloat: 1
diff --git a/sysdeps/x86_64/fpu/libm-test-ulps b/sysdeps/x86_64/fpu/libm-test-ulps
index 4767be9..f33dfed 100644
--- a/sysdeps/x86_64/fpu/libm-test-ulps
+++ b/sysdeps/x86_64/fpu/libm-test-ulps
@@ -162,6 +162,9 @@ ldouble: 1
 Test "atan2 (-0.75, -1.0) == -2.49809154479650885165983415456218025":
 float: 1
 ifloat: 1
+Test "atan2 (-max_value, -min_value) == -pi/2":
+float: 1
+ifloat: 1
 Test "atan2 (0.75, -1.0) == 2.49809154479650885165983415456218025":
 float: 1
 ifloat: 1
-- 
1.7.12.2.dirty


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