Algorithm Search⌘K

Proofs: Russian peasant multiplication

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

Russian peasant multiplication computes the exact product full

This proof shows: correctness, termination.

Let x0≥0x_0 \ge 0 and y0≥0y_0 \ge 0 be integers, the inputs of PEASANT-MUL.

Theorem. PEASANT-MUL(x0,y0)(x_0, y_0) terminates after exactly NN rounds of the loop of line L2, where N=0N = 0 if y0=0y_0 = 0 and N=⌊log⁡2y0⌋+1N = \lfloor \log_2 y_0 \rfloor + 1 otherwise, and it returns x0y0x_0 y_0.

Proof. Write xr,yr,prx_r, y_r, p_r for the values of x,y,px, y, p after rr rounds, so x0,y0x_0, y_0 are the inputs and p0=0p_0 = 0 by line L1. One round gives pr+1=pr+(yr mod 2) xrp_{r+1} = p_r + (y_r \bmod 2)\, x_r (line L3), xr+1=2xrx_{r+1} = 2x_r (line L4) and yr+1=⌊yr/2⌋y_{r+1} = \lfloor y_r / 2 \rfloor (line L5).

Invariant. We show pr+xryr=x0y0p_r + x_r y_r = x_0 y_0 for every rr for which round rr is reached. For r=0r = 0 this is 0+x0y0=x0y00 + x_0 y_0 = x_0 y_0. Assume it for rr, and that yr>0y_r > 0, so round r+1r + 1 runs. Division with remainder by 2 gives yr=2⌊yr/2⌋+(yr mod 2)=2yr+1+(yr mod 2)y_r = 2\lfloor y_r/2 \rfloor + (y_r \bmod 2) = 2 y_{r+1} + (y_r \bmod 2). Hence

pr+1+xr+1yr+1=pr+(yr mod 2) xr+2xryr+1=pr+xr(2yr+1+(yr mod 2))=pr+xryr=x0y0.p_{r+1} + x_{r+1} y_{r+1} = p_r + (y_r \bmod 2)\, x_r + 2 x_r y_{r+1} = p_r + x_r \big( 2 y_{r+1} + (y_r \bmod 2) \big) = p_r + x_r y_r = x_0 y_0 .

Termination. By induction, yr=⌊y0/2r⌋y_r = \lfloor y_0 / 2^r \rfloor, since ⌊⌊u/2r⌋/2⌋=⌊u/2r+1⌋\lfloor \lfloor u / 2^r \rfloor / 2 \rfloor = \lfloor u / 2^{r+1} \rfloor for integers u≥0u \ge 0. If y0=0y_0 = 0 the loop does not run, and N=0N = 0. If y0≥1y_0 \ge 1, then 2N−1≤y0<2N2^{N-1} \le y_0 < 2^N, so yr≥1y_r \ge 1 for r≤N−1r \le N - 1 and yN=0y_N = 0. The loop therefore runs exactly NN rounds and stops.

Result. When the loop stops, yN=0y_N = 0, and the invariant gives pN=x0y0−xN⋅0=x0y0p_N = x_0 y_0 - x_N \cdot 0 = x_0 y_0, which line L6 returns. All values stay nonnegative integers, since pp only grows by nonnegative terms, xx is doubled and yy is halved with the floor.

Limb arrays. In the implementation on limb arrays in radix β=2w\beta = 2^w, the parity of yy is the lowest bit of its lowest limb, since β\beta is even; the doubling shifts each limb left by one bit and carries its top bit into the next limb, which computes 2x2x exactly because 2∑ixiβi=∑i(2xi mod β)βi+∑i⌊2xi/β⌋βi+12\sum_i x_i \beta^i = \sum_i (2x_i \bmod \beta)\beta^i + \sum_i \lfloor 2x_i/\beta \rfloor \beta^{i+1} with ⌊2xi/β⌋∈{0,1}\lfloor 2x_i / \beta \rfloor \in \{0, 1\}; the halving is the reverse, ⌊y/2⌋=∑i(⌊yi/2⌋+(yi+1 mod 2) β/2)βi\lfloor y/2 \rfloor = \sum_i \big( \lfloor y_i / 2 \rfloor + (y_{i+1} \bmod 2)\,\beta/2 \big)\beta^i; and line L3 uses an exact multiprecision addition. So each line computes the value the argument above uses. ■\blacksquare

Back to Russian peasant multiplication