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: David Miller <davem@davemloft.net>
Date: Sun, 18 Nov 2012 18:39:29 -0500 (EST)

> Yes, this is exactly what the issue is here, and I have a patch
> I'm testing which returns {+,-}pi/2 immediately for large values
> instead of trying to compute the polynomial.

Due to a bug in my tracing I got the actual case wrong, the argument
to atanl() is actually 3.548665e-4516

So a tiny value.

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.

Something similar will need to be cooked up for ldbl-128ibm since it
suffers from the same issue and is generating the same spurious
underflows for the testsuite on powerpc.

While I'm waiting for feedback on the cutoff values to use, I'll work
on the new testcases.

2012-11-18  David S. Miller  <davem@davemloft.net>

	* sysdeps/ieee754/ldbl-128/s_atanl.c (__atanl): Handle tiny and
	very large arguments properly.

diff --git a/sysdeps/ieee754/ldbl-128/s_atanl.c b/sysdeps/ieee754/ldbl-128/s_atanl.c
index 0138e79..7534a88 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,12 +198,27 @@ __atanl (long double x)
 	return atantbl[83];
     }
 
+  if (k <= 0x3fc50000) /* |x| < 2**-58 */
+    {
+      /* Raise inexact. */
+      if (huge + x > 0.0)
+	return x;
+    }
+
   if (sign)
       x = -x;
 
   if (k >= 0x40024800) /* 10.25 */
     {
       k = 83;
+      if (k >= 0x40720000) /* |x| > 2**115 */
+	{
+	  /* Saturate result to {-,+}pi/2 */
+	  if (sign)
+	    return -atantbl[k];
+	  else
+	    return atantbl[k];
+	}
       t = -1.0/x;
     }
   else


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