← Propositiones
Principia P.000005 ·ARITHMETIC ·SEED

On multiplying great numbers by partition

De multiplicatione magnorum numerorum per partitionem

Discharged pending classO(n^log2(3)) ~ O(n^1.585) paradigmdivide_and_conquer falsifiable ifTwo n-digit integers may be multiplied with exactly three recursive half-length multiplications per level, yielding T(n)=3T(n/2)+O(n) and hence Theta(n^log2(3)) digit operations, strictly fewer than the schoolbook Theta(n^2) for all sufficiently large n.

Enuntiatio

Propositio V. Theorema. The product of two whole numbers, each of n digits, may be formed with no more than three multiplications of numbers of half the magnitude, together with a number of additions, subtractions, and shiftings proportional to n.

Let the multiplicands be split at the middle digit, so that x = a·B + b and y = c·B + d, where B = 10^m is the splitting base. The schoolbook expansion demands the four products ac, ad, bc, bd. I say that ad + bc is obtained from a single further product (a+b)(c+d) by subtracting the two products ac and bd already in hand; whence three multiplications suffice where four were thought necessary. Iterated upon the halves, this partition obeys the recurrence T(n) = 3·T(n/2) + O(n), and therefore consumes Θ(n^{log₂3}) ≈ Θ(n^{1.585}) digit-operations — for all sufficiently great n, strictly fewer than the Θ(n²) of multiplication by the schools.

Expressio

def karatsuba(x: int, y: int) -> int:
    """Multiply two integers by Karatsuba's three-product partition.

    Returns x * y exactly, using recursively three half-length
    multiplications in place of the schoolbook four.

    >>> karatsuba(1234, 5678)
    7006652
    >>> karatsuba(1234, 5678) == 1234 * 5678
    True
    >>> karatsuba(0, 999999)
    0
    >>> karatsuba(-31, 41) == -31 * 41
    True
    >>> all(karatsuba(i, j) == i * j for i in range(60) for j in range(60))
    True
    """
    # Reduce signed operands to the non-negative case.
    if x < 0 or y < 0:
        sign = -1 if (x < 0) ^ (y < 0) else 1
        return sign * karatsuba(abs(x), abs(y))

    # Base case: a single-digit factor is multiplied directly.
    if x < 10 or y < 10:
        return x * y

    # Split each operand at its middle digit: value = high * B + low.
    n = max(len(str(x)), len(str(y)))
    m = n // 2
    B = 10 ** m
    a, b = divmod(x, B)   # x = a*B + b,  0 <= b < B
    c, d = divmod(y, B)   # y = c*B + d,  0 <= d < B

    # Three recursive products, not four.
    ac = karatsuba(a, c)
    bd = karatsuba(b, d)
    ad_plus_bc = karatsuba(a + b, c + d) - ac - bd  # the Karatsuba identity

    # Recompose: x*y = ac*B^2 + (ad+bc)*B + bd.
    return ac * (10 ** (2 * m)) + ad_plus_bc * B + bd


if __name__ == "__main__":
    import doctest
    doctest.testmod()
    # Concrete witnesses of correctness.
    assert karatsuba(99, 99) == 9801
    assert karatsuba(31415926, 27182818) == 31415926 * 27182818
    assert karatsuba(2 ** 200, 3 ** 130) == (2 ** 200) * (3 ** 130)
    assert karatsuba(-123456789, 987654321) == -123456789 * 987654321
    print("Karatsuba verified.")

Demonstratio

The demonstration falls into two parts: first the correctness of the identity, then the cost of its iteration.

Part I — The identity is exact.

Let B = 10^m and write each n-digit operand in the radix-B positional form

x = a·B + b, y = c·B + d,

where a, c are the high parts and b, d the low parts, with 0 ≤ b, d < B. This is precisely what divmod(x, B) produces, so the split loses nothing. By the distributive law,

x·y = (aB + b)(cB + d) = ac·B² + (ad + bc)·B + bd. (∗)

The naive reading of (∗) requires the four products ac, ad, bc, bd. Now observe the algebraic step at the heart of the method:

(a + b)(c + d) = ac + ad + bc + bd,

and therefore

ad + bc = (a + b)(c + d) − ac − bd. (†)

The right side of (†) reuses ac and bd, which are already computed for (∗); the only new product is (a + b)(c + d). Substituting (†) into (∗) gives the recomposition coded above. Thus exactly three multiplications — ac, bd, and (a+b)(c+d) — produce all of x·y, the remaining operations being additions, subtractions, and multiplications by powers of ten (mere digit-shifts).

That the recursion terminates and is everywhere exact follows by strong induction on max(len(x), len(y)). Base: if either factor is below ten, the product is returned directly and is exact. Step: assume karatsuba multiplies exactly any pair of operands shorter than n digits. Because m = n//2 ≥ 1 whenever n ≥ 2, each of a, b, c, d is strictly shorter than n digits; and a + b, c + d each carry at most one digit beyond the half-length, hence remain strictly shorter than n digits as well. The three recursive calls therefore act on strictly smaller inputs and, by hypothesis, return exact products; equation (∗) combined with (†) then yields x·y exactly. The sign reduction at the top handles negatives by the law of signs and does not disturb the magnitude computation. Hence karatsuba(x, y) = x·y for all integers x, y. (This is what the inline assertions and the exhaustive small-input doctest confirm on concrete numbers.)

Part II — The cost is Θ(n^{log₂3}).

Let T(n) count the digit-operations to multiply two operands of at most n digits. The non-recursive work of one call — forming a, b, c, d by a split; the sums a+b and c+d; two subtractions; and the final shifts and additions — each touches O(n) digits, so it is bounded by c·n for some constant c. The three recursive calls each act on operands of at most ⌈n/2⌉ + 1 digits, which is n/2 + O(1); absorbing the additive constant into the analysis gives the recurrence

T(n) = 3·T(n/2) + O(n), T(1) = O(1). (‡)

Apply the Master Theorem with a = 3, b = 2, f(n) = Θ(n). The watershed exponent is

log_b a = log₂ 3 ≈ 1.58496.

Since f(n) = Θ(n^1) = O(n^{log₂3 − ε}) for any ε with 0 < ε < log₂3 − 1 (such ε exists because log₂3 − 1 ≈ 0.585 > 0), we are in Case 1 of the Master Theorem, the leaves of the recursion tree dominating the cost. Therefore

T(n) = Θ(n^{log₂3}) = Θ(n^{1.585}).

For the sceptic who distrusts the theorem, expand (‡) directly. At depth k there are 3^k subproblems, each of size n/2^k, contributing 3^k · c·(n/2^k) = c·n·(3/2)^k digit-operations. Summing over the k = 0,…,log₂n levels,

T(n) ≤ c·n · Σ_{k=0}^{log₂ n} (3/2)^k = c·n · ( (3/2)^{log₂n + 1} − 1 ) / ( 3/2 − 1 ) = O( n · (3/2)^{log₂ n} ).

But (3/2)^{log₂ n} = n^{log₂(3/2)} = n^{log₂3 − 1}, whence n · (3/2)^{log₂n} = n^{log₂3}, recovering T(n) = O(n^{log₂3}); the leaf-level alone contributes 3^{log₂n} = n^{log₂3} subproblems, giving the matching lower bound Ω(n^{log₂3}).

Finally, the comparison with the schoolbook method. School multiplication forms all n² digit-products, costing Θ(n²). Since log₂3 < 2, we have n^{log₂3} = o(n²); the ratio n²/n^{log₂3} = n^{2 − log₂3} = n^{0.415} → ∞. Hence for all sufficiently great n the partition method strictly dominates, as asserted.

Q.E.D.