1
0
mirror of https://sourceware.org/git/glibc.git synced 2025-07-29 11:41:21 +03:00

Use round-to-nearest internally in jn, test with ALL_RM_TEST (bug 18602).

Some existing jn tests, if run in non-default rounding modes, produce
errors above those accepted in glibc, which causes problems for moving
tests of jn to use ALL_RM_TEST.  This patch makes jn set rounding
to-nearest internally, as was done for yn some time ago, then computes
the appropriate underflowing value for results that underflowed to
zero in to-nearest, and moves the tests to ALL_RM_TEST.  It does
nothing about the general inaccuracy of Bessel function
implementations in glibc, though it should make jn more accurate on
average in non-default rounding modes through reduced error
accumulation.  The recomputation of results that underflowed to zero
should as a side-effect fix some cases of bug 16559, where jn just
used an exact zero, but that is *not* the goal of this patch and other
cases of that bug remain unfixed.

(Most of the changes in the patch are reindentation to add new scopes
for SET_RESTORE_ROUND*.)

Tested for x86_64, x86, powerpc and mips64.

	[BZ #16559]
	[BZ #18602]
	* sysdeps/ieee754/dbl-64/e_jn.c (__ieee754_jn): Set
	round-to-nearest internally then recompute results that
	underflowed to zero in the original rounding mode.
	* sysdeps/ieee754/flt-32/e_jnf.c (__ieee754_jnf): Likewise.
	* sysdeps/ieee754/ldbl-128/e_jnl.c (__ieee754_jnl): Likewise.
	* sysdeps/ieee754/ldbl-128ibm/e_jnl.c (__ieee754_jnl): Likewise.
	* sysdeps/ieee754/ldbl-96/e_jnl.c (__ieee754_jnl): Likewise
	* math/libm-test.inc (jn_test): Use ALL_RM_TEST.
	* sysdeps/i386/fpu/libm-test-ulps: Update.
	* sysdeps/x86_64/fpu/libm-test-ulps: Likewise.
This commit is contained in:
Joseph Myers
2015-06-25 21:46:02 +00:00
parent 037e4b993f
commit a8e2112ae3
10 changed files with 806 additions and 714 deletions

View File

@ -1,3 +1,18 @@
2015-06-25 Joseph Myers <joseph@codesourcery.com>
[BZ #16559]
[BZ #18602]
* sysdeps/ieee754/dbl-64/e_jn.c (__ieee754_jn): Set
round-to-nearest internally then recompute results that
underflowed to zero in the original rounding mode.
* sysdeps/ieee754/flt-32/e_jnf.c (__ieee754_jnf): Likewise.
* sysdeps/ieee754/ldbl-128/e_jnl.c (__ieee754_jnl): Likewise.
* sysdeps/ieee754/ldbl-128ibm/e_jnl.c (__ieee754_jnl): Likewise.
* sysdeps/ieee754/ldbl-96/e_jnl.c (__ieee754_jnl): Likewise
* math/libm-test.inc (jn_test): Use ALL_RM_TEST.
* sysdeps/i386/fpu/libm-test-ulps: Update.
* sysdeps/x86_64/fpu/libm-test-ulps: Likewise.
2015-06-25 Andrew Senkevich <andrew.senkevich@intel.com>
* NEWS: Fixed description of link with vector math library.

2
NEWS
View File

@ -25,7 +25,7 @@ Version 2.22
18498, 18507, 18512, 18513, 18519, 18520, 18522, 18527, 18528, 18529,
18530, 18532, 18533, 18534, 18536, 18539, 18540, 18542, 18544, 18545,
18546, 18547, 18549, 18553, 18558, 18569, 18583, 18585, 18586, 18593,
18594.
18594, 18602.
* Cache information can be queried via sysconf() function on s390 e.g. with
_SC_LEVEL1_ICACHE_SIZE as argument.

View File

@ -7486,9 +7486,7 @@ static const struct test_if_f_data jn_test_data[] =
static void
jn_test (void)
{
START (jn,, 0);
RUN_TEST_LOOP_if_f (jn, jn_test_data, );
END;
ALL_RM_TEST (jn, 0, jn_test_data, RUN_TEST_LOOP_if_f, END);
}

View File

@ -1613,6 +1613,30 @@ ifloat: 3
ildouble: 4
ldouble: 4
Function: "jn_downward":
double: 2
float: 3
idouble: 2
ifloat: 3
ildouble: 4
ldouble: 4
Function: "jn_towardzero":
double: 2
float: 3
idouble: 2
ifloat: 3
ildouble: 5
ldouble: 5
Function: "jn_upward":
double: 2
float: 3
idouble: 2
ifloat: 3
ildouble: 5
ldouble: 5
Function: "lgamma":
double: 1
float: 1

View File

@ -52,7 +52,7 @@ double
__ieee754_jn (int n, double x)
{
int32_t i, hx, ix, lx, sgn;
double a, b, temp, di;
double a, b, temp, di, ret;
double z, w;
/* J(-n,x) = (-1)^n * J(n, x), J(n, -x) = (-1)^n * J(n, x)
@ -75,9 +75,11 @@ __ieee754_jn (int n, double x)
return (__ieee754_j1 (x));
sgn = (n & 1) & (hx >> 31); /* even n -- 0, odd n -- sign(x) */
x = fabs (x);
{
SET_RESTORE_ROUND (FE_TONEAREST);
if (__glibc_unlikely ((ix | lx) == 0 || ix >= 0x7ff00000))
/* if x is 0 or inf */
b = zero;
return sgn == 1 ? -zero : zero;
else if ((double) n <= x)
{
/* Safe to use J(n+1,x)=2n/x *J(n,x)-J(n-1,x) */
@ -238,9 +240,13 @@ __ieee754_jn (int n, double x)
}
}
if (sgn == 1)
return -b;
ret = -b;
else
return b;
ret = b;
}
if (ret == 0)
ret = __copysign (DBL_MIN, ret) * DBL_MIN;
return ret;
}
strong_alias (__ieee754_jn, __jn_finite)

View File

@ -27,6 +27,8 @@ static const float zero = 0.0000000000e+00;
float
__ieee754_jnf(int n, float x)
{
float ret;
{
int32_t i,hx,ix, sgn;
float a, b, temp, di;
float z, w;
@ -47,8 +49,9 @@ __ieee754_jnf(int n, float x)
if(n==1) return(__ieee754_j1f(x));
sgn = (n&1)&(hx>>31); /* even n -- 0, odd n -- sign(x) */
x = fabsf(x);
SET_RESTORE_ROUNDF (FE_TONEAREST);
if(__builtin_expect(ix==0||ix>=0x7f800000, 0)) /* if x is 0 or inf */
b = zero;
return sgn == 1 ? -zero : zero;
else if((float)n<=x) {
/* Safe to use J(n+1,x)=2n/x *J(n,x)-J(n-1,x) */
a = __ieee754_j0f(x);
@ -163,7 +166,11 @@ __ieee754_jnf(int n, float x)
b = (t * w / a);
}
}
if(sgn==1) return -b; else return b;
if(sgn==1) ret = -b; else ret = b;
}
if (ret == 0)
ret = __copysignf (FLT_MIN, ret) * FLT_MIN;
return ret;
}
strong_alias (__ieee754_jnf, __jnf_finite)

View File

@ -73,7 +73,7 @@ __ieee754_jnl (int n, long double x)
{
u_int32_t se;
int32_t i, ix, sgn;
long double a, b, temp, di;
long double a, b, temp, di, ret;
long double z, w;
ieee854_long_double_shape_type u;
@ -106,8 +106,10 @@ __ieee754_jnl (int n, long double x)
sgn = (n & 1) & (se >> 31); /* even n -- 0, odd n -- sign(x) */
x = fabsl (x);
{
SET_RESTORE_ROUNDL (FE_TONEAREST);
if (x == 0.0L || ix >= 0x7fff0000) /* if x is 0 or inf */
b = zero;
return sgn == 1 ? -zero : zero;
else if ((long double) n <= x)
{
/* Safe to use J(n+1,x)=2n/x *J(n,x)-J(n-1,x) */
@ -289,9 +291,13 @@ __ieee754_jnl (int n, long double x)
}
}
if (sgn == 1)
return -b;
ret = -b;
else
return b;
ret = b;
}
if (ret == 0)
ret = __copysignl (LDBL_MIN, ret) * LDBL_MIN;
return ret;
}
strong_alias (__ieee754_jnl, __jnl_finite)

View File

@ -73,7 +73,7 @@ __ieee754_jnl (int n, long double x)
{
uint32_t se, lx;
int32_t i, ix, sgn;
long double a, b, temp, di;
long double a, b, temp, di, ret;
long double z, w;
double xhi;
@ -106,8 +106,10 @@ __ieee754_jnl (int n, long double x)
sgn = (n & 1) & (se >> 31); /* even n -- 0, odd n -- sign(x) */
x = fabsl (x);
{
SET_RESTORE_ROUNDL (FE_TONEAREST);
if (x == 0.0L || ix >= 0x7ff00000) /* if x is 0 or inf */
b = zero;
return sgn == 1 ? -zero : zero;
else if ((long double) n <= x)
{
/* Safe to use J(n+1,x)=2n/x *J(n,x)-J(n-1,x) */
@ -289,9 +291,13 @@ __ieee754_jnl (int n, long double x)
}
}
if (sgn == 1)
return -b;
ret = -b;
else
return b;
ret = b;
}
if (ret == 0)
ret = __copysignl (LDBL_MIN, ret) * LDBL_MIN;
return ret;
}
strong_alias (__ieee754_jnl, __jnl_finite)

View File

@ -71,7 +71,7 @@ __ieee754_jnl (int n, long double x)
{
u_int32_t se, i0, i1;
int32_t i, ix, sgn;
long double a, b, temp, di;
long double a, b, temp, di, ret;
long double z, w;
/* J(-n,x) = (-1)^n * J(n, x), J(n, -x) = (-1)^n * J(n, x)
@ -96,9 +96,11 @@ __ieee754_jnl (int n, long double x)
return (__ieee754_j1l (x));
sgn = (n & 1) & (se >> 15); /* even n -- 0, odd n -- sign(x) */
x = fabsl (x);
{
SET_RESTORE_ROUNDL (FE_TONEAREST);
if (__glibc_unlikely ((ix | i0 | i1) == 0 || ix >= 0x7fff))
/* if x is 0 or inf */
b = zero;
return sgn == 1 ? -zero : zero;
else if ((long double) n <= x)
{
/* Safe to use J(n+1,x)=2n/x *J(n,x)-J(n-1,x) */
@ -282,9 +284,13 @@ __ieee754_jnl (int n, long double x)
}
}
if (sgn == 1)
return -b;
ret = -b;
else
return b;
ret = b;
}
if (ret == 0)
ret = __copysignl (LDBL_MIN, ret) * LDBL_MIN;
return ret;
}
strong_alias (__ieee754_jnl, __jnl_finite)

View File

@ -1767,6 +1767,30 @@ ifloat: 4
ildouble: 4
ldouble: 4
Function: "jn_downward":
double: 5
float: 5
idouble: 5
ifloat: 5
ildouble: 4
ldouble: 4
Function: "jn_towardzero":
double: 5
float: 5
idouble: 5
ifloat: 5
ildouble: 5
ldouble: 5
Function: "jn_upward":
double: 5
float: 5
idouble: 5
ifloat: 5
ildouble: 5
ldouble: 5
Function: "lgamma":
double: 2
float: 2