diff options
author | Scott Turner <scotty@l5computing.com> | 2010-01-16 11:30:44 -0500 |
---|---|---|
committer | Jean-Baptiste Queru <jbq@google.com> | 2010-05-07 15:02:36 -0700 |
commit | c1f8dd9f0b0fe4d3953edefd2d6172573f6b7504 (patch) | |
tree | c101ce0c0a5b72ffc23b0aaebe6a6c3cc5313899 /libm | |
parent | 0be7eda75a14815aaa3e5cd5d5d4e5d25dc35d1c (diff) | |
download | bionic-c1f8dd9f0b0fe4d3953edefd2d6172573f6b7504.zip bionic-c1f8dd9f0b0fe4d3953edefd2d6172573f6b7504.tar.gz bionic-c1f8dd9f0b0fe4d3953edefd2d6172573f6b7504.tar.bz2 |
Sometimes the compiler is very right! Found bug in bessel routines for float.
Original compiler error:
target arm C: libm <= bionic/libm/src/e_j0f.c
bionic/libm/src/e_j0f.c: In function 'j0f':
bionic/libm/src/e_j0f.c:66: warning: comparison between signed and unsigned integer expressions
bionic/libm/src/e_j0f.c: In function 'y0f':
bionic/libm/src/e_j0f.c:140: warning: comparison between signed and unsigned integer expressions
target arm C: libm <= bionic/libm/src/e_j1.c
It's subtle but ix is masked with 0x7f000000 so it can never ever have a value
greater than 0x80000000. So I switched to using the unmasked hx and added a
cast as a reward to the compiler for being right.
I checked the original routines that e_j0f.c was ported from (in e_j0.c) and
the double's don't use 0x80000000 so this issue didn't exist there.
Let that be a warning to those that just slap on casts to shut up the compiler,
sometimes it's sniffed out a bug for you. :-)
Similar fixes in the other functions.
Change-Id: I7a776e5d4721fc3a9e3bd89179b67e9af3a2ebfa
Diffstat (limited to 'libm')
-rw-r--r-- | libm/src/e_j0f.c | 7 | ||||
-rw-r--r-- | libm/src/e_j1f.c | 3 | ||||
-rw-r--r-- | libm/src/e_jnf.c | 2 |
3 files changed, 7 insertions, 5 deletions
diff --git a/libm/src/e_j0f.c b/libm/src/e_j0f.c index b872406..6b566bf 100644 --- a/libm/src/e_j0f.c +++ b/libm/src/e_j0f.c @@ -1,5 +1,6 @@ /* e_j0f.c -- float version of e_j0.c. * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. + * Bugs in __ieee754_j0f and __ieee754_y0f fixed by Scott Turner 01/16/2010 */ /* @@ -63,7 +64,7 @@ __ieee754_j0f(float x) * j0(x) = 1/sqrt(pi) * (P(0,x)*cc - Q(0,x)*ss) / sqrt(x) * y0(x) = 1/sqrt(pi) * (P(0,x)*ss + Q(0,x)*cc) / sqrt(x) */ - if(ix>0x80000000) z = (invsqrtpi*cc)/sqrtf(x); + if(((uint32_t)hx)>0x80000000) z = (invsqrtpi*cc)/sqrtf(x); else { u = pzerof(x); v = qzerof(x); z = invsqrtpi*(u*cc-v*ss)/sqrtf(x); @@ -107,7 +108,7 @@ __ieee754_y0f(float x) int32_t hx,ix; GET_FLOAT_WORD(hx,x); - ix = 0x7fffffff&hx; + ix = hx&0x7fffffff; /* Y0(NaN) is NaN, y0(-inf) is Nan, y0(inf) is 0 */ if(ix>=0x7f800000) return one/(x+x*x); if(ix==0) return -one/zero; @@ -137,7 +138,7 @@ __ieee754_y0f(float x) if ((s*c)<zero) cc = z/ss; else ss = z/cc; } - if(ix>0x80000000) z = (invsqrtpi*ss)/sqrtf(x); + if(((uint32_t)hx)>0x80000000) z = (invsqrtpi*ss)/sqrtf(x); else { u = pzerof(x); v = qzerof(x); z = invsqrtpi*(u*ss+v*cc)/sqrtf(x); diff --git a/libm/src/e_j1f.c b/libm/src/e_j1f.c index 539399e..ea05774 100644 --- a/libm/src/e_j1f.c +++ b/libm/src/e_j1f.c @@ -1,5 +1,6 @@ /* e_j1f.c -- float version of e_j1.c. * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. + * Bug in __ieee754_j1f fixed by Scott Turner 1/16/2010 */ /* @@ -64,7 +65,7 @@ __ieee754_j1f(float x) * j1(x) = 1/sqrt(pi) * (P(1,x)*cc - Q(1,x)*ss) / sqrt(x) * y1(x) = 1/sqrt(pi) * (P(1,x)*ss + Q(1,x)*cc) / sqrt(x) */ - if(ix>0x80000000) z = (invsqrtpi*cc)/sqrtf(y); + if(((uint32_t)hx)>0x80000000) z = (invsqrtpi*cc)/sqrtf(y); else { u = ponef(y); v = qonef(y); z = invsqrtpi*(u*cc-v*ss)/sqrtf(y); diff --git a/libm/src/e_jnf.c b/libm/src/e_jnf.c index 029dba6..a61fb68 100644 --- a/libm/src/e_jnf.c +++ b/libm/src/e_jnf.c @@ -186,7 +186,7 @@ __ieee754_ynf(int n, float x) b = __ieee754_y1f(x); /* quit if b is -inf */ GET_FLOAT_WORD(ib,b); - for(i=1;i<n&&ib!=0xff800000;i++){ + for(i=1; i<n && (((uint32_t)ib) != 0xff800000); i++){ temp = b; b = ((float)(i+i)/x)*b - a; GET_FLOAT_WORD(ib,b); |