[Python-checkins] python/dist/src/Objects longobject.c,1.120,1.121

tim_one@users.sourceforge.net tim_one@users.sourceforge.net
Sun, 11 Aug 2002 19:31:21 -0700


Update of /cvsroot/python/python/dist/src/Objects
In directory usw-pr-cvs1:/tmp/cvs-serv7520/python/Objects

Modified Files:
	longobject.c 
Log Message:
Cautious introduction of a patch that started from
SF 560379:  Karatsuba multiplication.
Lots of things were changed from that.  This needs a lot more testing,
for correctness and speed, the latter especially when bit lengths are
unbalanced.  For now, the Karatsuba code gets invoked if and only if
envar KARAT exists.


Index: longobject.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Objects/longobject.c,v
retrieving revision 1.120
retrieving revision 1.121
diff -C2 -d -r1.120 -r1.121
*** longobject.c	17 Jul 2002 16:30:38 -0000	1.120
--- longobject.c	12 Aug 2002 02:31:19 -0000	1.121
***************
*** 9,14 ****
--- 9,25 ----
  #include <ctype.h>
  
+ /* For long multiplication, use the O(N**2) school algorithm unless
+  * both operands contain more than KARATSUBA_CUTOFF digits (this
+  * being an internal Python long digit, in base BASE).
+  */
+ #define KARATSUBA_CUTOFF 35
+ 
  #define ABS(x) ((x) < 0 ? -(x) : (x))
  
+ #undef MIN
+ #undef MAX
+ #define MAX(x, y) ((x) < (y) ? (y) : (x))
+ #define MIN(x, y) ((x) > (y) ? (y) : (x))
+ 
  /* Forward */
  static PyLongObject *long_normalize(PyLongObject *);
***************
*** 35,39 ****
  	int j = ABS(v->ob_size);
  	register int i = j;
! 	
  	while (i > 0 && v->ob_digit[i-1] == 0)
  		--i;
--- 46,50 ----
  	int j = ABS(v->ob_size);
  	register int i = j;
! 
  	while (i > 0 && v->ob_digit[i-1] == 0)
  		--i;
***************
*** 227,231 ****
  	unsigned long x, prev;
  	int i;
! 	
  	if (vv == NULL || !PyLong_Check(vv)) {
  		PyErr_BadInternalCall();
--- 238,242 ----
  	unsigned long x, prev;
  	int i;
! 
  	if (vv == NULL || !PyLong_Check(vv)) {
  		PyErr_BadInternalCall();
***************
*** 493,497 ****
  	PyErr_SetString(PyExc_OverflowError, "long too big to convert");
  	return -1;
! 	
  }
  
--- 504,508 ----
  	PyErr_SetString(PyExc_OverflowError, "long too big to convert");
  	return -1;
! 
  }
  
***************
*** 735,739 ****
  static int
  convert_binop(PyObject *v, PyObject *w, PyLongObject **a, PyLongObject **b) {
! 	if (PyLong_Check(v)) { 
  		*a = (PyLongObject *) v;
  		Py_INCREF(v);
--- 746,750 ----
  static int
  convert_binop(PyObject *v, PyObject *w, PyLongObject **a, PyLongObject **b) {
! 	if (PyLong_Check(v)) {
  		*a = (PyLongObject *) v;
  		Py_INCREF(v);
***************
*** 745,749 ****
  		return 0;
  	}
! 	if (PyLong_Check(w)) { 
  		*b = (PyLongObject *) w;
  		Py_INCREF(w);
--- 756,760 ----
  		return 0;
  	}
! 	if (PyLong_Check(w)) {
  		*b = (PyLongObject *) w;
  		Py_INCREF(w);
***************
*** 783,787 ****
  	twodigits carry = extra;
  	int i;
! 	
  	if (z == NULL)
  		return NULL;
--- 794,798 ----
  	twodigits carry = extra;
  	int i;
! 
  	if (z == NULL)
  		return NULL;
***************
*** 827,831 ****
  	const int size = ABS(a->ob_size);
  	PyLongObject *z;
! 	
  	assert(n > 0 && n <= MASK);
  	z = _PyLong_New(size);
--- 838,842 ----
  	const int size = ABS(a->ob_size);
  	PyLongObject *z;
! 
  	assert(n > 0 && n <= MASK);
  	z = _PyLong_New(size);
***************
*** 856,860 ****
  	}
  	assert(base >= 2 && base <= 36);
! 	
  	/* Compute a rough upper bound for the length of the string */
  	i = base;
--- 867,871 ----
  	}
  	assert(base >= 2 && base <= 36);
! 
  	/* Compute a rough upper bound for the length of the string */
  	i = base;
***************
*** 874,878 ****
  	if (a->ob_size < 0)
  		sign = '-';
! 	
  	if (a->ob_size == 0) {
  		*--p = '0';
--- 885,889 ----
  	if (a->ob_size < 0)
  		sign = '-';
! 
  	if (a->ob_size == 0) {
  		*--p = '0';
***************
*** 993,997 ****
  	char *start, *orig_str = str;
  	PyLongObject *z;
! 	
  	if ((base != 0 && base < 2) || base > 36) {
  		PyErr_SetString(PyExc_ValueError,
--- 1004,1008 ----
  	char *start, *orig_str = str;
  	PyLongObject *z;
! 
  	if ((base != 0 && base < 2) || base > 36) {
  		PyErr_SetString(PyExc_ValueError,
***************
*** 1024,1028 ****
  		int k = -1;
  		PyLongObject *temp;
! 		
  		if (*str <= '9')
  			k = *str - '0';
--- 1035,1039 ----
  		int k = -1;
  		PyLongObject *temp;
! 
  		if (*str <= '9')
  			k = *str - '0';
***************
*** 1054,1058 ****
  
   onError:
! 	PyErr_Format(PyExc_ValueError, 
  		     "invalid literal for long(): %.200s", orig_str);
  	Py_XDECREF(z);
--- 1065,1069 ----
  
   onError:
! 	PyErr_Format(PyExc_ValueError,
  		     "invalid literal for long(): %.200s", orig_str);
  	Py_XDECREF(z);
***************
*** 1093,1097 ****
  	int size_a = ABS(a->ob_size), size_b = ABS(b->ob_size);
  	PyLongObject *z;
! 	
  	if (size_b == 0) {
  		PyErr_SetString(PyExc_ZeroDivisionError,
--- 1104,1108 ----
  	int size_a = ABS(a->ob_size), size_b = ABS(b->ob_size);
  	PyLongObject *z;
! 
  	if (size_b == 0) {
  		PyErr_SetString(PyExc_ZeroDivisionError,
***************
*** 1143,1147 ****
  	PyLongObject *a;
  	int j, k;
! 	
  	if (v == NULL || w == NULL) {
  		Py_XDECREF(v);
--- 1154,1158 ----
  	PyLongObject *a;
  	int j, k;
! 
  	if (v == NULL || w == NULL) {
  		Py_XDECREF(v);
***************
*** 1149,1160 ****
  		return NULL;
  	}
! 	
  	assert(size_v >= size_w && size_w > 1); /* Assert checks by div() */
  	assert(v->ob_refcnt == 1); /* Since v will be used as accumulator! */
  	assert(size_w == ABS(w->ob_size)); /* That's how d was calculated */
! 	
  	size_v = ABS(v->ob_size);
  	a = _PyLong_New(size_v - size_w + 1);
! 	
  	for (j = size_v, k = a->ob_size-1; a != NULL && k >= 0; --j, --k) {
  		digit vj = (j >= size_v) ? 0 : v->ob_digit[j];
--- 1160,1171 ----
  		return NULL;
  	}
! 
  	assert(size_v >= size_w && size_w > 1); /* Assert checks by div() */
  	assert(v->ob_refcnt == 1); /* Since v will be used as accumulator! */
  	assert(size_w == ABS(w->ob_size)); /* That's how d was calculated */
! 
  	size_v = ABS(v->ob_size);
  	a = _PyLong_New(size_v - size_w + 1);
! 
  	for (j = size_v, k = a->ob_size-1; a != NULL && k >= 0; --j, --k) {
  		digit vj = (j >= size_v) ? 0 : v->ob_digit[j];
***************
*** 1162,1166 ****
  		stwodigits carry = 0;
  		int i;
! 		
  		SIGCHECK({
  			Py_DECREF(a);
--- 1173,1177 ----
  		stwodigits carry = 0;
  		int i;
! 
  		SIGCHECK({
  			Py_DECREF(a);
***************
*** 1173,1177 ****
  			q = (((twodigits)vj << SHIFT) + v->ob_digit[j-1]) /
  				w->ob_digit[size_w-1];
! 		
  		while (w->ob_digit[size_w-2]*q >
  				((
--- 1184,1188 ----
  			q = (((twodigits)vj << SHIFT) + v->ob_digit[j-1]) /
  				w->ob_digit[size_w-1];
! 
  		while (w->ob_digit[size_w-2]*q >
  				((
***************
*** 1182,1186 ****
  				+ v->ob_digit[j-2])
  			--q;
! 		
  		for (i = 0; i < size_w && i+k < size_v; ++i) {
  			twodigits z = w->ob_digit[i] * q;
--- 1193,1197 ----
  				+ v->ob_digit[j-2])
  			--q;
! 
  		for (i = 0; i < size_w && i+k < size_v; ++i) {
  			twodigits z = w->ob_digit[i] * q;
***************
*** 1193,1202 ****
  			carry -= zz;
  		}
! 		
  		if (i+k < size_v) {
  			carry += v->ob_digit[i+k];
  			v->ob_digit[i+k] = 0;
  		}
! 		
  		if (carry == 0)
  			a->ob_digit[k] = (digit) q;
--- 1204,1213 ----
  			carry -= zz;
  		}
! 
  		if (i+k < size_v) {
  			carry += v->ob_digit[i+k];
  			v->ob_digit[i+k] = 0;
  		}
! 
  		if (carry == 0)
  			a->ob_digit[k] = (digit) q;
***************
*** 1214,1218 ****
  		}
  	} /* for j, k */
! 	
  	if (a == NULL)
  		*prem = NULL;
--- 1225,1229 ----
  		}
  	} /* for j, k */
! 
  	if (a == NULL)
  		*prem = NULL;
***************
*** 1255,1259 ****
  {
  	int sign;
! 	
  	if (a->ob_size != b->ob_size) {
  		if (ABS(a->ob_size) == 0 && ABS(b->ob_size) == 0)
--- 1266,1270 ----
  {
  	int sign;
! 
  	if (a->ob_size != b->ob_size) {
  		if (ABS(a->ob_size) == 0 && ABS(b->ob_size) == 0)
***************
*** 1425,1429 ****
  {
  	PyLongObject *a, *b, *z;
! 	
  	CONVERT_BINOP((PyObject *)v, (PyObject *)w, &a, &b);
  
--- 1436,1440 ----
  {
  	PyLongObject *a, *b, *z;
! 
  	CONVERT_BINOP((PyObject *)v, (PyObject *)w, &a, &b);
  
***************
*** 1458,1509 ****
  }
  
! static PyObject *
! long_mul(PyLongObject *v, PyLongObject *w)
  {
! 	PyLongObject *a, *b, *z;
! 	int size_a;
! 	int size_b;
  	int i;
  
! 	if (!convert_binop((PyObject *)v, (PyObject *)w, &a, &b)) {
! 		if (!PyLong_Check(v) &&
! 		    v->ob_type->tp_as_sequence &&
! 		    v->ob_type->tp_as_sequence->sq_repeat)
! 			return long_repeat((PyObject *)v, w);
! 		if (!PyLong_Check(w) &&
! 			 w->ob_type->tp_as_sequence &&
! 			 w->ob_type->tp_as_sequence->sq_repeat)
! 			return long_repeat((PyObject *)w, v);
! 		Py_INCREF(Py_NotImplemented);
! 		return Py_NotImplemented;
! 	}
! 
! 	size_a = ABS(a->ob_size);
! 	size_b = ABS(b->ob_size);
! 	if (size_a > size_b) {
! 		/* we are faster with the small object on the left */
! 		int hold_sa = size_a;
! 		PyLongObject *hold_a = a;
! 		size_a = size_b;
! 		size_b = hold_sa;
! 		a = b;
! 		b = hold_a;
! 	}
! 	z = _PyLong_New(size_a + size_b);
! 	if (z == NULL) {
! 		Py_DECREF(a);
! 		Py_DECREF(b);
  		return NULL;
! 	}
! 	for (i = 0; i < z->ob_size; ++i)
! 		z->ob_digit[i] = 0;
  	for (i = 0; i < size_a; ++i) {
  		twodigits carry = 0;
  		twodigits f = a->ob_digit[i];
  		int j;
! 		
  		SIGCHECK({
- 			Py_DECREF(a);
- 			Py_DECREF(b);
  			Py_DECREF(z);
  			return NULL;
--- 1469,1494 ----
  }
  
! /* Grade school multiplication, ignoring the signs.
!  * Returns the absolute value of the product, or NULL if error.
!  */
! static PyLongObject *
! x_mul(PyLongObject *a, PyLongObject *b)
  {
! 	PyLongObject *z;
! 	int size_a = ABS(a->ob_size);
! 	int size_b = ABS(b->ob_size);
  	int i;
  
!      	z = _PyLong_New(size_a + size_b);
! 	if (z == NULL)
  		return NULL;
! 
! 	memset(z->ob_digit, 0, z->ob_size * sizeof(digit));
  	for (i = 0; i < size_a; ++i) {
  		twodigits carry = 0;
  		twodigits f = a->ob_digit[i];
  		int j;
! 
  		SIGCHECK({
  			Py_DECREF(z);
  			return NULL;
***************
*** 1521,1524 ****
--- 1506,1708 ----
  		}
  	}
+ 	return z;
+ }
+ 
+ /* A helper for Karatsuba multiplication (k_mul).
+    Takes a long "n" and an integer "size" representing the place to
+    split, and sets low and high such that abs(n) == (high << size) + low,
+    viewing the shift as being by digits.  The sign bit is ignored, and
+    the return values are >= 0.
+    Returns 0 on success, -1 on failure.
+ */
+ static int
+ kmul_split(PyLongObject *n, int size, PyLongObject **high, PyLongObject **low)
+ {
+ 	PyLongObject *hi, *lo;
+ 	int size_lo, size_hi;
+ 	const int size_n = ABS(n->ob_size);
+ 
+ 	size_lo = MIN(size_n, size);
+ 	size_hi = size_n - size_lo;
+ 
+ 	if ((hi = _PyLong_New(size_hi)) == NULL)
+ 		return -1;
+ 	if ((lo = _PyLong_New(size_lo)) == NULL) {
+ 		Py_DECREF(hi);
+ 		return -1;
+ 	}
+ 
+ 	memcpy(lo->ob_digit, n->ob_digit, size_lo * sizeof(digit));
+ 	memcpy(hi->ob_digit, n->ob_digit + size_lo, size_hi * sizeof(digit));
+ 
+ 	*high = long_normalize(hi);
+ 	*low = long_normalize(lo);
+ 	return 0;
+ }
+ 
+ /* Karatsuba multiplication.  Ignores the input signs, and returns the
+  * absolute value of the product (or NULL if error).
+  * See Knuth Vol. 2 Chapter 4.3.3 (Pp. 294-295).
+  */
+ static PyLongObject *
+ k_mul(PyLongObject *a, PyLongObject *b)
+ {
+ 	PyLongObject *ah = NULL;
+ 	PyLongObject *al = NULL;
+ 	PyLongObject *bh = NULL;
+ 	PyLongObject *bl = NULL;
+ 	PyLongObject *albl = NULL;
+ 	PyLongObject *ahbh = NULL;
+ 	PyLongObject *k = NULL;
+ 	PyLongObject *ret = NULL;
+ 	PyLongObject *t1, *t2;
+ 	int shift;	/* the number of digits we split off */
+ 	int i;
+ 
+ 	/* (ah*X+al)(bh*X+bl) = ah*bh*X*X + (ah*bl + al*bh)*X + al*bl
+ 	 * Let k = (ah+al)*(bh+bl) = ah*bl + al*bh  + ah*bh + al*bl
+ 	 * Then the original product is
+ 	 *     ah*bh*X*X + (k - ah*bh - ah*bl)*X + al*bl
+ 	 * By picking X to be a power of 2, "*X" is just shifting, and it's
+ 	 * been reduced to 3 multiplies on numbers half the size.
+ 	 */
+ 
+ 	/* We want to split based on the larger number; fiddle so that a
+ 	 * is largest.
+ 	 */
+ 	if (ABS(a->ob_size) > ABS(b->ob_size)) {
+ 		t1 = a;
+ 		a = b;
+ 		b = t1;
+ 	}
+ 
+ 	/* Use gradeschool math when either number is too small. */
+ 	if (ABS(a->ob_size) <= KARATSUBA_CUTOFF)
+ 		return x_mul(a, b);
+ 
+ 	shift = ABS(b->ob_size) >> 1;
+ 	if (kmul_split(a, shift, &ah, &al) < 0) goto fail;
+ 	if (kmul_split(b, shift, &bh, &bl) < 0) goto fail;
+ 
+ 	if ((ahbh = k_mul(ah, bh)) == NULL) goto fail;
+ 	assert(ahbh->ob_size >= 0);
+ 
+ 	/* Allocate result space, and copy ahbh into the high digits. */
+ 	ret = _PyLong_New(ahbh->ob_size + 2*shift + 1);
+ 	if (ret == NULL) goto fail;
+ #ifdef Py_DEBUG
+ 	/* Fill with trash, to catch reference to uninitialized digits. */
+ 	memset(ret->ob_digit, 0xDF, ret->ob_size * sizeof(digit));
+ #endif
+ 	memcpy(ret->ob_digit + 2*shift, ahbh->ob_digit,
+ 	       ahbh->ob_size * sizeof(digit));
+ 	/* That didn't copy into the most-significant (overflow) digit. */
+ 	ret->ob_digit[ret->ob_size - 1] = 0;
+ 
+ 	/* Compute al*bl, and copy into the low digits. */
+ 	if ((albl = k_mul(al, bl)) == NULL) goto fail;
+ 	assert(albl->ob_size >= 0);
+ 	assert(albl->ob_size <= 2*shift); /* no overlap with high digits */
+ 	memcpy(ret->ob_digit, albl->ob_digit, albl->ob_size * sizeof(digit));
+ 
+ 	/* Zero out remaining digits. */
+ 	i = 2*shift - albl->ob_size;	/* number of uninitialized digits */
+ 	if (i)
+ 		memset(ret->ob_digit + albl->ob_size, 0, i * sizeof(digit));
+ 
+ 	/* k = (ah+al)(bh+bl) */
+ 	if ((t1 = x_add(ah, al)) == NULL) goto fail;
+ 	Py_DECREF(ah);
+ 	Py_DECREF(al);
+ 	ah = al = NULL;
+ 
+ 	if ((t2 = x_add(bh, bl)) == NULL) {
+ 		Py_DECREF(t1);
+ 		goto fail;
+ 	}
+ 	Py_DECREF(bh);
+ 	Py_DECREF(bl);
+ 	bh = bl = NULL;
+ 
+ 	k = k_mul(t1, t2);
+ 	Py_DECREF(t1);
+ 	Py_DECREF(t2);
+ 	if (k == NULL) goto fail;
+ 
+ 	/* Subtract ahbh and albl from k.  Note that this can't become
+ 	 * negative, since k = ahbh + albl + other stuff.
+ 	 */
+ 	if ((t1 = x_sub(k, ahbh)) == NULL) goto fail;
+ 	Py_DECREF(k);
+ 	k = t1;
+ 	Py_DECREF(ahbh);
+ 	ahbh = NULL;
+ 
+ 	if ((t1 = x_sub(k, albl)) == NULL) goto fail;
+ 	Py_DECREF(k);
+ 	k = t1;
+ 	Py_DECREF(albl);
+ 	albl = NULL;
+ 
+ 	/* Add k into the result, at the shift-th least-significant digit. */
+ 	{
+ 		int j;		/* index into k */
+ 		digit carry = 0;
+ 
+ 		for (i = shift, j = 0; j < k->ob_size; ++i, ++j) {
+ 			carry += ret->ob_digit[i] + k->ob_digit[j];
+ 			ret->ob_digit[i] = carry & MASK;
+ 			carry >>= SHIFT;
+ 		}
+ 		for (; carry && i < ret->ob_size; ++i) {
+ 			carry += ret->ob_digit[i];
+ 			ret->ob_digit[i] = carry & MASK;
+ 			carry >>= SHIFT;
+ 		}
+ 		assert(carry == 0);
+ 	}
+ 	Py_DECREF(k);
+ 	return long_normalize(ret);
+ 
+  fail:
+  	Py_XDECREF(ret);
+ 	Py_XDECREF(ah);
+ 	Py_XDECREF(al);
+ 	Py_XDECREF(bh);
+ 	Py_XDECREF(bl);
+ 	Py_XDECREF(ahbh);
+ 	Py_XDECREF(albl);
+ 	Py_XDECREF(k);
+ 	return NULL;
+ }
+ 
+ 
+ static PyObject *
+ long_mul(PyLongObject *v, PyLongObject *w)
+ {
+ 	PyLongObject *a, *b, *z;
+ 
+ 	if (!convert_binop((PyObject *)v, (PyObject *)w, &a, &b)) {
+ 		if (!PyLong_Check(v) &&
+ 		    v->ob_type->tp_as_sequence &&
+ 		    v->ob_type->tp_as_sequence->sq_repeat)
+ 			return long_repeat((PyObject *)v, w);
+ 		if (!PyLong_Check(w) &&
+ 		    w->ob_type->tp_as_sequence &&
+ 		    w->ob_type->tp_as_sequence->sq_repeat)
+ 			return long_repeat((PyObject *)w, v);
+ 		Py_INCREF(Py_NotImplemented);
+ 		return Py_NotImplemented;
+ 	}
+ 
+ 	if (Py_GETENV("KARAT") != NULL)
+ 		z = k_mul(a, b);
+ 	else
+ 		z = x_mul(a, b);
+ 	if(z == NULL) {
+ 		Py_DECREF(a);
+ 		Py_DECREF(b);
+ 		return NULL;
+ 	}
  	if (a->ob_size < 0)
  		z->ob_size = -(z->ob_size);
***************
*** 1546,1554 ****
  
  static int
! l_divmod(PyLongObject *v, PyLongObject *w, 
  	 PyLongObject **pdiv, PyLongObject **pmod)
  {
  	PyLongObject *div, *mod;
! 	
  	if (long_divrem(v, w, &div, &mod) < 0)
  		return -1;
--- 1730,1738 ----
  
  static int
! l_divmod(PyLongObject *v, PyLongObject *w,
  	 PyLongObject **pdiv, PyLongObject **pmod)
  {
  	PyLongObject *div, *mod;
! 
  	if (long_divrem(v, w, &div, &mod) < 0)
  		return -1;
***************
*** 1658,1662 ****
  		"long/long too large for a float");
  	return NULL;
! 	
  }
  
--- 1842,1846 ----
  		"long/long too large for a float");
  	return NULL;
! 
  }
  
***************
*** 1715,1719 ****
  
  	CONVERT_BINOP(v, w, &a, &b);
! 	if (PyLong_Check(x) || Py_None == x) { 
  		c = x;
  		Py_INCREF(x);
--- 1899,1903 ----
  
  	CONVERT_BINOP(v, w, &a, &b);
! 	if (PyLong_Check(x) || Py_None == x) {
  		c = x;
  		Py_INCREF(x);
***************
*** 1755,1762 ****
  		digit bi = b->ob_digit[i];
  		int j;
! 	
  		for (j = 0; j < SHIFT; ++j) {
  			PyLongObject *temp;
! 		
  			if (bi & 1) {
  				temp = (PyLongObject *)long_mul(z, a);
--- 1939,1946 ----
  		digit bi = b->ob_digit[i];
  		int j;
! 
  		for (j = 0; j < SHIFT; ++j) {
  			PyLongObject *temp;
! 
  			if (bi & 1) {
  				temp = (PyLongObject *)long_mul(z, a);
***************
*** 1887,1891 ****
  	int newsize, wordshift, loshift, hishift, i, j;
  	digit lomask, himask;
! 	
  	CONVERT_BINOP((PyObject *)v, (PyObject *)w, &a, &b);
  
--- 2071,2075 ----
  	int newsize, wordshift, loshift, hishift, i, j;
  	digit lomask, himask;
! 
  	CONVERT_BINOP((PyObject *)v, (PyObject *)w, &a, &b);
  
***************
*** 1904,1908 ****
  	}
  	else {
! 		
  		shiftby = PyLong_AsLong((PyObject *)b);
  		if (shiftby == -1L && PyErr_Occurred())
--- 2088,2092 ----
  	}
  	else {
! 
  		shiftby = PyLong_AsLong((PyObject *)b);
  		if (shiftby == -1L && PyErr_Occurred())
***************
*** 1954,1958 ****
  	int oldsize, newsize, wordshift, remshift, i, j;
  	twodigits accum;
! 	
  	CONVERT_BINOP(v, w, &a, &b);
  
--- 2138,2142 ----
  	int oldsize, newsize, wordshift, remshift, i, j;
  	twodigits accum;
! 
  	CONVERT_BINOP(v, w, &a, &b);
  
***************
*** 1984,1988 ****
  	for (i = 0; i < wordshift; i++)
  		z->ob_digit[i] = 0;
! 	accum = 0;	
  	for (i = wordshift, j = 0; j < oldsize; i++, j++) {
  		accum |= a->ob_digit[j] << remshift;
--- 2168,2172 ----
  	for (i = 0; i < wordshift; i++)
  		z->ob_digit[i] = 0;
! 	accum = 0;
  	for (i = wordshift, j = 0; j < oldsize; i++, j++) {
  		accum |= a->ob_digit[j] << remshift;
***************
*** 1992,1996 ****
  	if (remshift)
  		z->ob_digit[newsize-1] = (digit)accum;
! 	else	
  		assert(!accum);
  	z = long_normalize(z);
--- 2176,2180 ----
  	if (remshift)
  		z->ob_digit[newsize-1] = (digit)accum;
! 	else
  		assert(!accum);
  	z = long_normalize(z);
***************
*** 2004,2012 ****
  /* Bitwise and/xor/or operations */
  
- #undef MIN
- #undef MAX
- #define MAX(x, y) ((x) < (y) ? (y) : (x))
- #define MIN(x, y) ((x) > (y) ? (y) : (x))
- 
  static PyObject *
  long_bitwise(PyLongObject *a,
--- 2188,2191 ----
***************
*** 2021,2025 ****
  	digit diga, digb;
  	PyObject *v;
! 	
  	if (a->ob_size < 0) {
  		a = (PyLongObject *) long_invert(a);
--- 2200,2204 ----
  	digit diga, digb;
  	PyObject *v;
! 
  	if (a->ob_size < 0) {
  		a = (PyLongObject *) long_invert(a);
***************
*** 2038,2042 ****
  		maskb = 0;
  	}
! 	
  	negz = 0;
  	switch (op) {
--- 2217,2221 ----
  		maskb = 0;
  	}
! 
  	negz = 0;
  	switch (op) {
***************
*** 2064,2068 ****
  		break;
  	}
! 	
  	/* JRH: The original logic here was to allocate the result value (z)
  	   as the longer of the two operands.  However, there are some cases
--- 2243,2247 ----
  		break;
  	}
! 
  	/* JRH: The original logic here was to allocate the result value (z)
  	   as the longer of the two operands.  However, there are some cases
***************
*** 2089,2093 ****
  		return NULL;
  	}
! 	
  	for (i = 0; i < size_z; ++i) {
  		diga = (i < size_a ? a->ob_digit[i] : 0) ^ maska;
--- 2268,2272 ----
  		return NULL;
  	}
! 
  	for (i = 0; i < size_z; ++i) {
  		diga = (i < size_a ? a->ob_digit[i] : 0) ^ maska;
***************
*** 2099,2103 ****
  		}
  	}
! 	
  	Py_DECREF(a);
  	Py_DECREF(b);
--- 2278,2282 ----
  		}
  	}
! 
  	Py_DECREF(a);
  	Py_DECREF(b);