From bd0383acf89b9ed392bcf16ed89622cb2b33753b Mon Sep 17 00:00:00 2001 From: Jack Ren Date: Sat, 19 Nov 2011 15:52:08 +0800 Subject: [PATCH] libm: fix invalid result of function remquo/remquof Currently we will get the wrong result as follows: remquof(0x7bb33336, 0x63000000) = -671088640, 0x00000000 remquo(0xbff0000000000003, 0x3ff0000000000003) = 1, 0x8000000000000000 remquo(0x9120000000000001, 0x0000000000000005) = -1288490188, 0x0000000000000004 while the correct one should be: remquof(0x7bb33336, 0x63000000) = 1476395008, 0x00000000 remquo(0xbff0000000000003, 0x3ff0000000000003) = -1, 0x8000000000000000 remquo(0x9120000000000001, 0x0000000000000005) = -1288490189, 0x0000000000000001 Fixed in this patch. Change-Id: I540b348cd10a539f3b39b1753945c893c4c7ec46 Signed-off-by: Jingwei Zhang Signed-off-by: Jin Wei Signed-off-by: Jack Ren Signed-off-by: Bruce Beare --- libm/src/s_remquo.c | 9 +++++---- libm/src/s_remquof.c | 5 +++-- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/libm/src/s_remquo.c b/libm/src/s_remquo.c index eee65df4f..9ad1e4c27 100644 --- a/libm/src/s_remquo.c +++ b/libm/src/s_remquo.c @@ -49,7 +49,7 @@ remquo(double x, double y, int *quo) goto fixup; /* |x|<|y| return x or x-y */ } if(lx==ly) { - *quo = 1; + *quo = (sxy ? -1 : 1); return Zero[(u_int32_t)sx>>31]; /* |x|=|y| return x*0*/ } } @@ -112,7 +112,8 @@ remquo(double x, double y, int *quo) /* convert back to floating value and restore the sign */ if((hx|lx)==0) { /* return sign(x)*0 */ - *quo = (sxy ? -q : q); + q &= 0x7fffffff; + *quo = (sxy ? -q : q); return Zero[(u_int32_t)sx>>31]; } while(hx<0x00100000) { /* normalize x */ @@ -127,9 +128,9 @@ remquo(double x, double y, int *quo) lx = (lx>>n)|((u_int32_t)hx<<(32-n)); hx >>= n; } else if (n<=31) { - lx = (hx<<(32-n))|(lx>>n); hx = sx; + lx = (hx<<(32-n))|(lx>>n); hx = 0; } else { - lx = hx>>(n-32); hx = sx; + lx = hx>>(n-32); hx = 0; } } fixup: diff --git a/libm/src/s_remquof.c b/libm/src/s_remquof.c index 5d722ceaf..43e05cb14 100644 --- a/libm/src/s_remquof.c +++ b/libm/src/s_remquof.c @@ -46,7 +46,7 @@ remquof(float x, float y, int *quo) q = 0; goto fixup; /* |x|<|y| return x or x-y */ } else if(hx==hy) { - *quo = 1; + *quo = (sxy ? -1 : 1); return Zero[(u_int32_t)sx>>31]; /* |x|=|y| return x*0*/ } @@ -88,7 +88,8 @@ remquof(float x, float y, int *quo) /* convert back to floating value and restore the sign */ if(hx==0) { /* return sign(x)*0 */ - *quo = (sxy ? -q : q); + q &= 0x7fffffff; + *quo = (sxy ? -q : q); return Zero[(u_int32_t)sx>>31]; } while(hx<0x00800000) { /* normalize x */