Algorithm Search⌘K

Proofs: Schoolbook multiplication

These are the human proofs of Schoolbook multiplication, at full length.

Schoolbook multiplication computes the exact product in m + n limbs full

This proof shows: correctness, termination.

Let β=2w\beta = 2^w, let a=[a0,…,am−1]a = [a_0, \ldots, a_{m-1}] and b=[b0,…,bn−1]b = [b_0, \ldots, b_{n-1}] be arrays of limbs (0≤ai,bj≤β−10 \le a_i, b_j \le \beta - 1), and let A=∑iaiβiA = \sum_i a_i \beta^i and B=∑jbjβjB = \sum_j b_j \beta^j. For an array cc of m+nm + n entries write V(c)=∑k=0m+n−1ckβkV(c) = \sum_{k=0}^{m+n-1} c_k \beta^k, and Ai=∑i′<iai′βi′A_i = \sum_{i' < i} a_{i'}\beta^{i'}, so A0=0A_0 = 0 and Am=AA_m = A.

Theorem. SCHOOLBOOK-MUL(a,b)(a, b) terminates and returns an array cc of m+nm + n limbs, each in [0,β−1][0, \beta - 1], with V(c)=ABV(c) = AB.

Proof. Both loops have fixed bounds, so the procedure terminates after mnmn runs of the inner body. We prove an invariant of the outer loop.

(O) Before row ii (that is, before line L3 with this ii), each ckc_k is a limb, ck=0c_k = 0 for each k≥i+nk \ge i + n, and V(c)=Ai⋅BV(c) = A_i \cdot B.

Initialization. Line L1 sets all ck=0c_k = 0, so V(c)=0=A0BV(c) = 0 = A_0 B, and every ckc_k is 0.

Maintenance. Fix ii with 0≤i<m0 \le i < m and assume (O). Let c(0)c^{(0)} be the array before row ii. For the inner loop we prove:

(I) Before step jj of the inner loop (0≤j≤n0 \le j \le n), 0≤carry≤β−10 \le \text{carry} \le \beta - 1, the entries ci,…,ci+j−1c_{i}, \ldots, c_{i+j-1} are limbs, the other entries are those of c(0)c^{(0)}, and ∑k=ii+j−1ckβk+carry⋅βi+j=∑k=ii+j−1ck(0)βk+ai(∑j′<jbj′βj′)βi.\displaystyle \sum_{k=i}^{i+j-1} c_k \beta^{k} + \text{carry}\cdot\beta^{i+j} = \sum_{k=i}^{i+j-1} c^{(0)}_k \beta^k + a_i \Big(\sum_{j' < j} b_{j'} \beta^{j'}\Big) \beta^i .

For j=0j = 0, line L3 sets carry to 0 and both sides are 0. In step jj, line L5 forms t=ci+j(0)+aibj+carryt = c^{(0)}_{i+j} + a_i b_j + \text{carry}; the entry ci+jc_{i+j} is still the old one by (I). All three terms are nonnegative, and t≤(β−1)+(β−1)2+(β−1)=β2−1t \le (\beta - 1) + (\beta - 1)^2 + (\beta - 1) = \beta^2 - 1. Lines L6 and L7 write t=ci+j+carry′βt = c_{i+j} + \text{carry}' \beta with ci+j=t mod β∈[0,β−1]c_{i+j} = t \bmod \beta \in [0, \beta - 1] and carry′=⌊t/β⌋≤⌊(β2−1)/β⌋=β−1\text{carry}' = \lfloor t / \beta \rfloor \le \lfloor (\beta^2 - 1)/\beta \rfloor = \beta - 1. So

ci+jβi+j+carry′βi+j+1=t βi+j=ci+j(0)βi+j+carry⋅βi+j+aibjβi+j.c_{i+j}\beta^{i+j} + \text{carry}'\beta^{i+j+1} = t\,\beta^{i+j} = c^{(0)}_{i+j}\beta^{i+j} + \text{carry}\cdot\beta^{i+j} + a_i b_j \beta^{i+j} .

Adding this to (I) for jj gives (I) for j+1j + 1.

After the inner loop, (I) with j=nj = n holds. Line L8 stores carry in ci+nc_{i+n}. By (O), ci+n(0)=0c^{(0)}_{i+n} = 0, so this store adds carry⋅βi+n\text{carry}\cdot\beta^{i+n} to V(c)V(c) and replaces nothing. Hence, with (I) for j=nj = n, the new array satisfies

V(c)=V(c(0))+aiBβi=AiB+aiβiB=Ai+1B.V(c) = V(c^{(0)}) + a_i B \beta^i = A_i B + a_i \beta^i B = A_{i+1} B .

Each entry is a limb: the entries ci,…,ci+n−1c_i, \ldots, c_{i+n-1} by (I), ci+n=carry≤β−1c_{i+n} = \text{carry} \le \beta - 1, and the others are unchanged. The entries with index k≥i+1+nk \ge i + 1 + n were not written in row ii, so they are still 0. Thus (O) holds for i+1i + 1.

Termination. For i=mi = m, (O) gives V(c)=AmB=ABV(c) = A_m B = AB, with every entry a limb. Line L9 returns this array, of m+nm + n limbs. ■\blacksquare

Remark (no row writes a fresh position twice). The maintenance step uses ci+n(0)=0c^{(0)}_{i+n} = 0. This is the second part of (O): row i′<ii' < i writes only positions i′,…,i′+ni', \ldots, i' + n, all below i+ni + n.

Remark (signs). For signed inputs, AB=sign⁡(A)sign⁡(B) ∣A∣ ∣B∣AB = \operatorname{sign}(A)\operatorname{sign}(B)\,|A|\,|B|, so multiplying the magnitudes with this procedure and setting the sign by the product of the signs is correct; a zero product is given the sign ++.

Back to Schoolbook multiplication