Index: longobject.c =================================================================== --- longobject.c (revision 66563) +++ longobject.c (working copy) @@ -2495,18 +2495,48 @@ } } else { /* a is not the same as b -- gradeschool long mult */ - for (i = 0; i < size_a; ++i) { - twodigits carry = 0; - twodigits f = a->ob_digit[i]; + for (i = 0; i < size_a - 1; i += 2) { + twodigits f0 = a->ob_digit[i]; + twodigits f1 = a->ob_digit[i+1]; digit *pz = z->ob_digit + i; digit *pb = b->ob_digit; - digit *pbend = b->ob_digit + size_b; + twodigits carry = *pz + pb[0] * f0; + *pz++ = (digit)(carry & PyLong_MASK); + carry >>= PyLong_SHIFT; SIGCHECK({ Py_DECREF(z); return NULL; }) - + int j; + /* carry + *pz + pb[j+1] * f0 + pb[j] * f1 <= + * 2*MASK + 2*MASK*MASK is contained in a twodigits, + * see longintrepr.h */ + for(j=0; j < size_b-1; j++) { + carry += *pz + pb[j+1] * f0 + pb[j] * f1; + *pz++ = (digit)(carry & PyLong_MASK); + carry >>= PyLong_SHIFT; + assert(carry <= PyLong_MASK); + } + carry += *pz + pb[size_b-1] * f1; + *pz++ = (digit)(carry & PyLong_MASK); + carry >>= PyLong_SHIFT; + if (carry) + *pz += (digit)(carry & PyLong_MASK); + assert((carry >> PyLong_SHIFT) == 0); + } + if (size_a&1) { + twodigits carry = 0; + twodigits f = a->ob_digit[size_a - 1]; + digit *pz = z->ob_digit + size_a - 1; + digit *pb = b->ob_digit; + digit *pbend = b->ob_digit + size_b; + + SIGCHECK({ + Py_DECREF(z); + return NULL; + }) + while (pb < pbend) { carry += *pz + *pb++ * f; *pz++ = (digit)(carry & PyLong_MASK);