From e61ffaea2a1232e4fc817c3a0154711f85952b6d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ulrich=20Sp=C3=B6rlein?= Date: Sat, 13 Nov 2010 10:54:10 +0000 Subject: [PATCH] Fix bug in jn(3) and jnf(3) that led to -inf results Explanation by Steve: jn[f](n,x) for certain ranges of x uses downward recursion to compute the value of the function. The recursion sequence that is generated is proportional to the actual desired value, so a normalization step is taken. This normalization is j0[f](x) divided by the zeroth sequence member. As Bruce notes, near the zeros of j0[f](x) the computed value can have giga-ULP inaccuracy. I found for the 1st zero of j0f(x) only the leading decimal digit is correct. The solution to the issue is fairly straight forward. The zeros of j0(x) and j1(x) never coincide, so as j0(x) approaches a zero, the normalization constant switches to j1[f](x) divided by the 2nd sequence member. The expectation is that j1[f](x) is a more accurately computed value. PR: bin/144306 Submitted by: Steven G. Kargl Reviewed by: bde MFC after: 7 days --- lib/msun/src/e_jn.c | 7 ++++++- lib/msun/src/e_jnf.c | 7 ++++++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/lib/msun/src/e_jn.c b/lib/msun/src/e_jn.c index e277e3014c7b..8b0bc62efc2c 100644 --- a/lib/msun/src/e_jn.c +++ b/lib/msun/src/e_jn.c @@ -200,7 +200,12 @@ __ieee754_jn(int n, double x) } } } - b = (t*__ieee754_j0(x)/b); + z = __ieee754_j0(x); + w = __ieee754_j1(x); + if (fabs(z) >= fabs(w)) + b = (t*z/b); + else + b = (t*w/a); } } if(sgn==1) return -b; else return b; diff --git a/lib/msun/src/e_jnf.c b/lib/msun/src/e_jnf.c index 3bbf7b71ed14..f564aeccd655 100644 --- a/lib/msun/src/e_jnf.c +++ b/lib/msun/src/e_jnf.c @@ -152,7 +152,12 @@ __ieee754_jnf(int n, float x) } } } - b = (t*__ieee754_j0f(x)/b); + z = __ieee754_j0f(x); + w = __ieee754_j1f(x); + if (fabsf(z) >= fabsf(w)) + b = (t*z/b); + else + b = (t*w/a); } } if(sgn==1) return -b; else return b;