[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);