[Python-checkins] CVS: python/dist/src/Objects intobject.c,2.56,2.57
Tim Peters
tim_one@users.sourceforge.net
Mon, 18 Jun 2001 12:21:13 -0700
Update of /cvsroot/python/python/dist/src/Objects
In directory usw-pr-cvs1:/tmp/cvs-serv27024/python/dist/src/Objects
Modified Files:
intobject.c
Log Message:
SF bug 434186: 0x80000000/2 != 0x80000000>>1
i_divmod: New and simpler algorithm. Old one returned gibberish on most
boxes when the numerator was -sys.maxint-1. Oddly enough, it worked in the
release (not debug) build on Windows, because the compiler optimized away
some tricky sign manipulations that were incorrect in this case.
Makes you wonder <wink> ...
Bugfix candidate.
Index: intobject.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Objects/intobject.c,v
retrieving revision 2.56
retrieving revision 2.57
diff -C2 -r2.56 -r2.57
*** intobject.c 2001/03/06 12:12:02 2.56
--- intobject.c 2001/06/18 19:21:11 2.57
***************
*** 435,470 ****
static int
! i_divmod(register long xi, register long yi,
long *p_xdivy, long *p_xmody)
{
long xdivy, xmody;
! if (yi == 0) {
PyErr_SetString(PyExc_ZeroDivisionError,
"integer division or modulo by zero");
return -1;
}
! if (yi < 0) {
! if (xi < 0) {
! if (yi == -1 && -xi < 0) {
! /* most negative / -1 */
! err_ovf("integer division");
! return -1;
! }
! xdivy = -xi / -yi;
! }
! else
! xdivy = - (xi / -yi);
! }
! else {
! if (xi < 0)
! xdivy = - (-xi / yi);
! else
! xdivy = xi / yi;
}
! xmody = xi - xdivy*yi;
! if ((xmody < 0 && yi > 0) || (xmody > 0 && yi < 0)) {
! xmody += yi;
! xdivy -= 1;
}
*p_xdivy = xdivy;
--- 435,464 ----
static int
! i_divmod(register long x, register long y,
long *p_xdivy, long *p_xmody)
{
long xdivy, xmody;
! if (y == 0) {
PyErr_SetString(PyExc_ZeroDivisionError,
"integer division or modulo by zero");
return -1;
}
! /* (-sys.maxint-1)/-1 is the only overflow case. */
! if (y == -1 && x < 0 && x == -x) {
! err_ovf("integer division");
! return -1;
}
! xdivy = x / y;
! xmody = x - xdivy * y;
! /* If the signs of x and y differ, and the remainder is non-0,
! * C89 doesn't define whether xdivy is now the floor or the
! * ceiling of the infinitely precise quotient. We want the floor,
! * and we have it iff the remainder's sign matches y's.
! */
! if (xmody && ((y ^ xmody) < 0) /* i.e. and signs differ */) {
! xmody += y;
! --xdivy;
! assert(xmody && ((y ^ xmody) >= 0));
}
*p_xdivy = xdivy;