aboutsummaryrefslogtreecommitdiff
path: root/sysdeps
diff options
context:
space:
mode:
authorJoseph Myers <joseph@codesourcery.com>2015-02-25 11:13:41 +0000
committerJoseph Myers <joseph@codesourcery.com>2015-02-25 11:13:41 +0000
commit137cef7d433407bd2ded8bcc5bea70e5858df47a (patch)
treedeb0a6e04c5e7220d1e4eebcf59ab9d792a8eca6 /sysdeps
parentcb43bb0d68f001fc3d6e054d712ab8794b5fd1de (diff)
downloadglibc-137cef7d433407bd2ded8bcc5bea70e5858df47a.tar
glibc-137cef7d433407bd2ded8bcc5bea70e5858df47a.tar.gz
glibc-137cef7d433407bd2ded8bcc5bea70e5858df47a.tar.bz2
glibc-137cef7d433407bd2ded8bcc5bea70e5858df47a.zip
Fix ldbl-128ibm asinhl inaccuracy (bug 18020).
The ldbl-128ibm implementation of asinhl uses cut-offs of 0x1p28 and 0x1p-29 to determine when to use simpler formulas that avoid possible overflow / underflow. Both those cut-offs are inappropriate for this format, resulting in large errors. This patch changes the code to use more appropriate cut-offs of 0x1p56 and 0x1p-56, adding tests around the cut-offs for various floating-point formats. Tested for powerpc. Also tested for x86_64 and x86 and updated ulps. [BZ #18020] * sysdeps/ieee754/ldbl-128ibm/s_asinhl.c (__asinhl): Use 2**56 and 2**-56 not 2**28 and 2**-29 as thresholds for simpler formulas. * math/auto-libm-test-in: Add more tests of asinh. * math/auto-libm-test-out: Regenerated. * sysdeps/i386/fpu/libm-test-ulps: Update. * sysdeps/x86_64/fpu/libm-test-ulps: Likewise.
Diffstat (limited to 'sysdeps')
-rw-r--r--sysdeps/i386/fpu/libm-test-ulps8
-rw-r--r--sysdeps/ieee754/ldbl-128ibm/s_asinhl.c8
-rw-r--r--sysdeps/x86_64/fpu/libm-test-ulps27
3 files changed, 22 insertions, 21 deletions
diff --git a/sysdeps/i386/fpu/libm-test-ulps b/sysdeps/i386/fpu/libm-test-ulps
index 0977557f02..3ba23a4fc5 100644
--- a/sysdeps/i386/fpu/libm-test-ulps
+++ b/sysdeps/i386/fpu/libm-test-ulps
@@ -68,14 +68,14 @@ ldouble: 1
Function: "asinh_downward":
double: 1
float: 1
-ildouble: 1
+ildouble: 3
ldouble: 3
Function: "asinh_towardzero":
double: 1
float: 1
-ildouble: 1
-ldouble: 2
+ildouble: 3
+ldouble: 3
Function: "asinh_upward":
double: 1
@@ -83,7 +83,7 @@ float: 1
idouble: 1
ifloat: 1
ildouble: 5
-ldouble: 2
+ldouble: 3
Function: "atan2":
ildouble: 1
diff --git a/sysdeps/ieee754/ldbl-128ibm/s_asinhl.c b/sysdeps/ieee754/ldbl-128ibm/s_asinhl.c
index 043b151fff..b76e114317 100644
--- a/sysdeps/ieee754/ldbl-128ibm/s_asinhl.c
+++ b/sysdeps/ieee754/ldbl-128ibm/s_asinhl.c
@@ -44,15 +44,15 @@ long double __asinhl(long double x)
EXTRACT_WORDS64 (hx, xhi);
ix = hx&0x7fffffffffffffffLL;
if(ix>=0x7ff0000000000000LL) return x+x; /* x is inf or NaN */
- if(ix< 0x3e20000000000000LL) { /* |x|<2**-29 */
+ if(ix< 0x3c70000000000000LL) { /* |x|<2**-56 */
if(huge+x>one) return x; /* return x inexact except 0 */
}
- if(ix>0x41b0000000000000LL) { /* |x| > 2**28 */
+ if(ix>0x4370000000000000LL) { /* |x| > 2**56 */
w = __ieee754_logl(fabsl(x))+ln2;
- } else if (ix>0x4000000000000000LL) { /* 2**28 > |x| > 2.0 */
+ } else if (ix>0x4000000000000000LL) { /* 2**56 >= |x| > 2.0 */
t = fabs(x);
w = __ieee754_logl(2.0*t+one/(__ieee754_sqrtl(x*x+one)+t));
- } else { /* 2.0 > |x| > 2**-29 */
+ } else { /* 2.0 >= |x| >= 2**-56 */
t = x*x;
w =__log1pl(fabsl(x)+t/(one+__ieee754_sqrtl(one+t)));
}
diff --git a/sysdeps/x86_64/fpu/libm-test-ulps b/sysdeps/x86_64/fpu/libm-test-ulps
index cd9e44f4a4..72529291b8 100644
--- a/sysdeps/x86_64/fpu/libm-test-ulps
+++ b/sysdeps/x86_64/fpu/libm-test-ulps
@@ -86,33 +86,34 @@ ldouble: 1
Function: "asinh":
double: 1
float: 1
+idouble: 1
ifloat: 1
ildouble: 1
ldouble: 1
Function: "asinh_downward":
-double: 1
+double: 2
float: 2
-idouble: 1
-ifloat: 1
-ildouble: 1
+idouble: 2
+ifloat: 2
+ildouble: 3
ldouble: 3
Function: "asinh_towardzero":
-double: 1
-float: 1
-idouble: 1
-ifloat: 1
-ildouble: 1
-ldouble: 2
+double: 2
+float: 2
+idouble: 2
+ifloat: 2
+ildouble: 3
+ldouble: 3
Function: "asinh_upward":
double: 2
float: 1
-idouble: 1
+idouble: 2
ifloat: 1
-ildouble: 2
-ldouble: 2
+ildouble: 3
+ldouble: 3
Function: "atan2":
float: 1