This is the mail archive of the
libc-alpha@sourceware.org
mailing list for the glibc project.
Re: k_sinl bug fix for ldbl-128 and ldbl-128ibm
On Fri, 16 Mar 2012, Joseph S. Myers wrote:
> On Thu, 15 Mar 2012, David Miller wrote:
>
> > This gives new ULPs on sparc, this is test-ldouble.out:
>
> Hopefully it also reduces some ULPs (which is less visible) so being on
> average better (as was the case when making this fix for ldbl-96).
>
> I had the idea last night that this issue only affected k_sinl, but on
> looking at it again I think k_cosl is affected as well (and k_sincosl,
> which I didn't pay much attention to because I'm keeping the existing
> ldbl-96 s_sincosl for now which doesn't use k_sincosl). So I'll post
> revised versions of both patches that fix those other functions as well.
Like so. The corresponding cosl fix for ldbl-96 reduces the number of
ulps changes for test-ldouble on x86 from 20 to 16 (fixing sinl having
reduced the number from 30 to 20). (These are figures in the presence of
the testsuite changes from the ldbl-96 patch - so include both ULPs for
tests that patch newly enables as well as ULPs for tests that were already
being run for long double.)
2012-03-16 Joseph Myers <joseph@codesourcery.com>
* sysdeps/ieee754/ldbl-128/k_cosl.c (__kernel_cosl): Negate y if
negating x to take absolute value.
* sysdeps/ieee754/ldbl-128/k_sincosl.c (__kernel_sincosl):
Likewise.
* sysdeps/ieee754/ldbl-128ibm/k_cosl.c (__kernel_cosl): Likewise.
* sysdeps/ieee754/ldbl-128ibm/k_sincosl.c (__kernel_sincosl):
Likewise.
* sysdeps/ieee754/ldbl-128/k_sinl.c (__kernel_sinl): Negate y when
computing low part if x was negated.
* sysdeps/ieee754/ldbl-128ibm/k_sinl.c (__kernel_sinl): Likewise.
diff --git a/sysdeps/ieee754/ldbl-128/k_cosl.c b/sysdeps/ieee754/ldbl-128/k_cosl.c
index 4cb9dd1..aa447ec 100644
--- a/sysdeps/ieee754/ldbl-128/k_cosl.c
+++ b/sysdeps/ieee754/ldbl-128/k_cosl.c
@@ -105,7 +105,11 @@ __kernel_cosl(long double x, long double y)
cosl(h+l) = cosl(h)cosl(l) - sinl(h)sinl(l). */
index = 0x3ffe - (tix >> 16);
hix = (tix + (0x200 << index)) & (0xfffffc00 << index);
- x = fabsl (x);
+ if (signbit (x))
+ {
+ x = -x;
+ y = -y;
+ }
switch (index)
{
case 0: index = ((45 << 10) + hix - 0x3ffe0000) >> 8; break;
diff --git a/sysdeps/ieee754/ldbl-128/k_sincosl.c b/sysdeps/ieee754/ldbl-128/k_sincosl.c
index 98c5d62..00a21c4 100644
--- a/sysdeps/ieee754/ldbl-128/k_sincosl.c
+++ b/sysdeps/ieee754/ldbl-128/k_sincosl.c
@@ -132,7 +132,11 @@ __kernel_sincosl(long double x, long double y, long double *sinx, long double *c
cosl(h+l) = cosl(h)cosl(l) - sinl(h)sinl(l). */
index = 0x3ffe - (tix >> 16);
hix = (tix + (0x200 << index)) & (0xfffffc00 << index);
- x = fabsl (x);
+ if (signbit (x))
+ {
+ x = -x;
+ y = -y;
+ }
switch (index)
{
case 0: index = ((45 << 10) + hix - 0x3ffe0000) >> 8; break;
diff --git a/sysdeps/ieee754/ldbl-128/k_sinl.c b/sysdeps/ieee754/ldbl-128/k_sinl.c
index 6eaf878..1f0ca8c 100644
--- a/sysdeps/ieee754/ldbl-128/k_sinl.c
+++ b/sysdeps/ieee754/ldbl-128/k_sinl.c
@@ -116,7 +116,7 @@ __kernel_sinl(long double x, long double y, int iy)
SET_LDOUBLE_WORDS64(h, ((u_int64_t)hix) << 32, 0);
if (iy)
- l = y - (h - x);
+ l = (ix < 0 ? -y : y) - (h - x);
else
l = x - h;
z = l * l;
diff --git a/sysdeps/ieee754/ldbl-128ibm/k_cosl.c b/sysdeps/ieee754/ldbl-128ibm/k_cosl.c
index 5241431..fc01374 100644
--- a/sysdeps/ieee754/ldbl-128ibm/k_cosl.c
+++ b/sysdeps/ieee754/ldbl-128ibm/k_cosl.c
@@ -123,7 +123,11 @@ __kernel_cosl(long double x, long double y)
index = 0x3fe - (tix >> 20);
hix = (tix + (0x200 << index)) & (0xfffffc00 << index);
- x = fabsl (x);
+ if (signbit (x))
+ {
+ x = -x;
+ y = -y;
+ }
switch (index)
{
case 0: index = ((45 << 14) + hix - 0x3fe00000) >> 12; break;
diff --git a/sysdeps/ieee754/ldbl-128ibm/k_sincosl.c b/sysdeps/ieee754/ldbl-128ibm/k_sincosl.c
index f3dd954..98fe07d 100644
--- a/sysdeps/ieee754/ldbl-128ibm/k_sincosl.c
+++ b/sysdeps/ieee754/ldbl-128ibm/k_sincosl.c
@@ -151,7 +151,11 @@ __kernel_sincosl(long double x, long double y, long double *sinx, long double *c
index = 0x3fe - (tix >> 20);
hix = (tix + (0x2000 << index)) & (0xffffc000 << index);
- x = fabsl (x);
+ if (signbit (x))
+ {
+ x = -x;
+ y = -y;
+ }
switch (index)
{
case 0: index = ((45 << 14) + hix - 0x3fe00000) >> 12; break;
diff --git a/sysdeps/ieee754/ldbl-128ibm/k_sinl.c b/sysdeps/ieee754/ldbl-128ibm/k_sinl.c
index 484b65f..94aba0b 100644
--- a/sysdeps/ieee754/ldbl-128ibm/k_sinl.c
+++ b/sysdeps/ieee754/ldbl-128ibm/k_sinl.c
@@ -134,7 +134,7 @@ __kernel_sinl(long double x, long double y, int iy)
*/
SET_LDOUBLE_WORDS64(h, ((u_int64_t)hix) << 32, 0);
if (iy)
- l = y - (h - x);
+ l = (ix < 0 ? -y : y) - (h - x);
else
l = x - h;
z = l * l;
--
Joseph S. Myers
joseph@codesourcery.com