Fix ldbl-128ibm asinhl inaccuracy (bug 18020) [committed]

Message ID alpine.DEB.2.10.1502251114080.4161@digraph.polyomino.org.uk
State Committed
Headers

Commit Message

Joseph Myers Feb. 25, 2015, 11:14 a.m. UTC
  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.
Committed.

(auto-libm-test-out diffs omitted below.)

2015-02-25  Joseph Myers  <joseph@codesourcery.com>

	[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.
  

Patch

diff --git a/math/auto-libm-test-in b/math/auto-libm-test-in
index a4bd972..df51c26 100644
--- a/math/auto-libm-test-in
+++ b/math/auto-libm-test-in
@@ -104,8 +104,69 @@  asinh 1
 asinh 10
 asinh 100
 asinh 1e6
+asinh 0x1p8
+asinh 0x1p9
+asinh 0x1p10
+asinh 0x1p11
+asinh 0x1p12
+asinh 0x1p13
+asinh 0x1p24
+asinh 0x1p25
+asinh 0x1p26
+asinh 0x1p27
+asinh 0x1p28
+asinh 0x1p29
+asinh 0x1p30
+asinh 0x1p31
+asinh 0x1p32
+asinh 0x1p33
+asinh 0x1p48
+asinh 0x1p49
+asinh 0x1p50
+asinh 0x1p51
+asinh 0x1p52
+asinh 0x1p53
+asinh 0x1p54
+asinh 0x1p55
+asinh 0x1p56
+asinh 0x1p57
+asinh 0x1p58
+asinh 0x1p59
 asinh 0x1p100
+asinh 0x1p500
+asinh 0x1p5000
+asinh 0x1p-8
+asinh 0x1p-9
+asinh 0x1p-10
+asinh 0x1p-11
+asinh 0x1p-12
+asinh 0x1p-13
+asinh 0x1p-24
+asinh 0x1p-25
+asinh 0x1p-26
+asinh 0x1p-27
+asinh 0x1p-28
+asinh 0x1p-29
+asinh 0x1p-30
+asinh 0x1p-31
+asinh 0x1p-32
+asinh 0x1p-33
+asinh 0x1p-48
+asinh 0x1p-49
+asinh 0x1p-50
+asinh 0x1p-51
+asinh 0x1p-52
+asinh 0x1p-53
+asinh 0x1p-54
+asinh 0x1p-55
+asinh 0x1p-56
+asinh 0x1p-57
+asinh 0x1p-58
+asinh 0x1p-59
+asinh 0x1p-100
 # Bug 16350: underflow exception may be missing.
+asinh 0x1p-500 missing-underflow
+asinh 0x1p-5000 missing-underflow
 asinh min missing-underflow
 asinh -min missing-underflow
 asinh min_subnorm missing-underflow
diff --git a/sysdeps/i386/fpu/libm-test-ulps b/sysdeps/i386/fpu/libm-test-ulps
index 0977557..3ba23a4 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 043b151..b76e114 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 cd9e44f..7252929 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