@@ -775,6 +775,57 @@ convert_binop(PyObject *v, PyObject *w, PyLongObject **a, PyLongObject **b) {
775775 return Py_NotImplemented; \
776776 }
777777
778+ /* x[0:m] and y[0:n] are digit vectors, LSD first, m >= n required. x[0:n]
779+ * is modified in place, by adding y to it. Carries are propagated as far as
780+ * x[m-1], and the remaining carry (0 or 1) is returned.
781+ */
782+ static digit
783+ v_iadd (digit * x , int m , digit * y , int n )
784+ {
785+ int i ;
786+ digit carry = 0 ;
787+
788+ assert (m >= n );
789+ for (i = 0 ; i < n ; ++ i ) {
790+ carry += x [i ] + y [i ];
791+ x [i ] = carry & MASK ;
792+ carry >>= SHIFT ;
793+ assert ((carry & 1 ) == carry );
794+ }
795+ for (; carry && i < m ; ++ i ) {
796+ carry += x [i ];
797+ x [i ] = carry & MASK ;
798+ carry >>= SHIFT ;
799+ assert ((carry & 1 ) == carry );
800+ }
801+ return carry ;
802+ }
803+
804+ /* x[0:m] and y[0:n] are digit vectors, LSD first, m >= n required. x[0:n]
805+ * is modified in place, by subtracting y from it. Borrows are propagated as
806+ * far as x[m-1], and the remaining borrow (0 or 1) is returned.
807+ */
808+ static digit
809+ v_isub (digit * x , int m , digit * y , int n )
810+ {
811+ int i ;
812+ digit borrow = 0 ;
813+
814+ assert (m >= n );
815+ for (i = 0 ; i < n ; ++ i ) {
816+ borrow = x [i ] - y [i ] - borrow ;
817+ x [i ] = borrow & MASK ;
818+ borrow >>= SHIFT ;
819+ borrow &= 1 ; /* keep only 1 sign bit */
820+ }
821+ for (; borrow && i < m ; ++ i ) {
822+ borrow = x [i ] - borrow ;
823+ x [i ] = borrow & MASK ;
824+ borrow >>= SHIFT ;
825+ borrow &= 1 ;
826+ }
827+ return borrow ;
828+ }
778829
779830/* Multiply by a single digit, ignoring the sign. */
780831
@@ -1558,7 +1609,9 @@ k_mul(PyLongObject *a, PyLongObject *b)
15581609 PyLongObject * t1 , * t2 ;
15591610 int shift ; /* the number of digits we split off */
15601611 int i ;
1561-
1612+ #ifdef Py_DEBUG
1613+ digit d ;
1614+ #endif
15621615 /* (ah*X+al)(bh*X+bl) = ah*bh*X*X + (ah*bl + al*bh)*X + al*bl
15631616 * Let k = (ah+al)*(bh+bl) = ah*bl + al*bh + ah*bh + al*bl
15641617 * Then the original product is
@@ -1629,39 +1682,32 @@ k_mul(PyLongObject *a, PyLongObject *b)
16291682 Py_DECREF (t2 );
16301683 if (k == NULL ) goto fail ;
16311684
1632- /* Subtract ahbh and albl from k. Note that this can't become
1633- * negative, since k = ahbh + albl + other stuff.
1634- */
1635- if ((t1 = x_sub (k , ahbh )) == NULL ) goto fail ;
1685+ /* Add k into the result, starting at the shift'th LSD. */
1686+ i = ret -> ob_size - shift ; /* # digits after shift */
1687+ #ifdef Py_DEBUG
1688+ d =
1689+ #endif
1690+ v_iadd (ret -> ob_digit + shift , i , k -> ob_digit , k -> ob_size );
1691+ assert (d == 0 );
16361692 Py_DECREF (k );
1637- k = t1 ;
1693+
1694+ /* Subtract ahbh and albl from the result. Note that this can't
1695+ * become negative, since k = ahbh + albl + other stuff.
1696+ */
1697+ #ifdef Py_DEBUG
1698+ d =
1699+ #endif
1700+ v_isub (ret -> ob_digit + shift , i , ahbh -> ob_digit , ahbh -> ob_size );
1701+ assert (d == 0 );
16381702 Py_DECREF (ahbh );
1639- ahbh = NULL ;
16401703
1641- if ((t1 = x_sub (k , albl )) == NULL ) goto fail ;
1642- Py_DECREF (k );
1643- k = t1 ;
1704+ #ifdef Py_DEBUG
1705+ d =
1706+ #endif
1707+ v_isub (ret -> ob_digit + shift , i , albl -> ob_digit , albl -> ob_size );
1708+ assert (d == 0 );
16441709 Py_DECREF (albl );
1645- albl = NULL ;
16461710
1647- /* Add k into the result, at the shift-th least-significant digit. */
1648- {
1649- int j ; /* index into k */
1650- digit carry = 0 ;
1651-
1652- for (i = shift , j = 0 ; j < k -> ob_size ; ++ i , ++ j ) {
1653- carry += ret -> ob_digit [i ] + k -> ob_digit [j ];
1654- ret -> ob_digit [i ] = carry & MASK ;
1655- carry >>= SHIFT ;
1656- }
1657- for (; carry && i < ret -> ob_size ; ++ i ) {
1658- carry += ret -> ob_digit [i ];
1659- ret -> ob_digit [i ] = carry & MASK ;
1660- carry >>= SHIFT ;
1661- }
1662- assert (carry == 0 );
1663- }
1664- Py_DECREF (k );
16651711 return long_normalize (ret );
16661712
16671713 fail :
0 commit comments