Skip to content

Commit 5a33b6b

Browse files
ararslanDavid Schultz
and
David Schultz
authored
Fix a bug in remquo{,f,l}, in which the quotient didn't always have the correct sign when the remainder was 0. (#317)
Fix a separate bug in remquo alone, in which the remainder and quotient were both off by a bit in certain cases involving subnormal remainders. The bugs affected all platforms except amd64 and i386, on which the routines are implemented in assembly. PR: 166463 Submitted by: Ilya Burylov MFC after: 2 weeks Co-authored-by: David Schultz <[email protected]>
1 parent 798e808 commit 5a33b6b

File tree

3 files changed

+8
-5
lines changed

3 files changed

+8
-5
lines changed

src/s_remquo.c

+4-3
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ remquo(double x, double y, int *quo)
5151
goto fixup; /* |x|<|y| return x or x-y */
5252
}
5353
if(lx==ly) {
54-
*quo = 1;
54+
*quo = (sxy ? -1 : 1);
5555
return Zero[(u_int32_t)sx>>31]; /* |x|=|y| return x*0*/
5656
}
5757
}
@@ -114,6 +114,7 @@ remquo(double x, double y, int *quo)
114114

115115
/* convert back to floating value and restore the sign */
116116
if((hx|lx)==0) { /* return sign(x)*0 */
117+
q &= 0x7fffffff;
117118
*quo = (sxy ? -q : q);
118119
return Zero[(u_int32_t)sx>>31];
119120
}
@@ -129,9 +130,9 @@ remquo(double x, double y, int *quo)
129130
lx = (lx>>n)|((u_int32_t)hx<<(32-n));
130131
hx >>= n;
131132
} else if (n<=31) {
132-
lx = (hx<<(32-n))|(lx>>n); hx = sx;
133+
lx = (hx<<(32-n))|(lx>>n); hx = 0;
133134
} else {
134-
lx = hx>>(n-32); hx = sx;
135+
lx = hx>>(n-32); hx = 0;
135136
}
136137
}
137138
fixup:

src/s_remquof.c

+2-1
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ remquof(float x, float y, int *quo)
4747
q = 0;
4848
goto fixup; /* |x|<|y| return x or x-y */
4949
} else if(hx==hy) {
50-
*quo = 1;
50+
*quo = (sxy ? -1 : 1);
5151
return Zero[(u_int32_t)sx>>31]; /* |x|=|y| return x*0*/
5252
}
5353

@@ -89,6 +89,7 @@ remquof(float x, float y, int *quo)
8989

9090
/* convert back to floating value and restore the sign */
9191
if(hx==0) { /* return sign(x)*0 */
92+
q &= 0x7fffffff;
9293
*quo = (sxy ? -q : q);
9394
return Zero[(u_int32_t)sx>>31];
9495
}

src/s_remquol.c

+2-1
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ remquol(long double x, long double y, int *quo)
9696
goto fixup; /* |x|<|y| return x or x-y */
9797
}
9898
if(ux.bits.manh==uy.bits.manh && ux.bits.manl==uy.bits.manl) {
99-
*quo = 1;
99+
*quo = (sxy ? -1 : 1);
100100
return Zero[sx]; /* |x|=|y| return x*0*/
101101
}
102102
}
@@ -138,6 +138,7 @@ remquol(long double x, long double y, int *quo)
138138

139139
/* convert back to floating value and restore the sign */
140140
if((hx|lx)==0) { /* return sign(x)*0 */
141+
q &= 0x7fffffff;
141142
*quo = (sxy ? -q : q);
142143
return Zero[sx];
143144
}

0 commit comments

Comments
 (0)