The operations on multiprecision integers are exact and keep the representation normalized full
This proof shows: correctness.
We write β=2w, and for a list of limbs a we write mag(a)=∑i=0∣a∣−1aiβi. A pair (s,a) is normalized when it meets (N): a∣a∣−1=0 if ∣a∣>0, and s=+ if ∣a∣=0. A list c with c∣c∣−1=0 or ∣c∣=0 is a normalized list.
Fact 1 (length and size). If a is a normalized list with ∣a∣=k≥1, then βk−1≤mag(a)≤βk−1. Proof. The top term is at least βk−1 and the other terms are nonnegative. Each limb is at most β−1, so mag(a)≤(β−1)∑i<kβi=βk−1. □
Lemma 1 (CMP-MAG). For normalized lists a and b, CMP-MAG(a,b) returns the sign of mag(a)−mag(b).
Proof. If ∣a∣>∣b∣, then ∣a∣≥1 and, by Fact 1, mag(a)≥β∣a∣−1≥β∣b∣>mag(b); the empty list b has magnitude 0<mag(a) too. So line C1 is right, and the case ∣a∣<∣b∣ is symmetric. Let ∣a∣=∣b∣=k. If a=b, the loop of lines C2 and C3 finds no difference and line C4 returns 0. Otherwise let i be the largest index with ai=bi; the loop finds this i first, because it runs down from k−1. Say ai>bi, so ai−bi≥1. Then
mag(a)−mag(b)=(ai−bi)βi+j<i∑(aj−bj)βj≥βi−(β−1)j<i∑βj=βi−(βi−1)=1, and line C3 returns 1. The case ai<bi is symmetric. □
Lemma 2 (ADD-MAG). For lists a and b of limbs with m=∣a∣≥∣b∣=n, ADD-MAG returns a list c of limbs with mag(c)=mag(a)+mag(b). If a is a normalized list, so is c.
Proof. Write bi=0 for i≥n. We prove the invariant
(A) at the start of step i of the loop of line L8, c0,…,ci−1 are limbs, carry∈{0,1}, and ∑j<icjβj+carry⋅βi=∑j<i(aj+bj)βj.
Initialization. For i=0, line L7 sets carry to 0, and both sides are 0.
Maintenance. In step i, line L9 sets t=ai+bi+carry, so 0≤t≤2(β−1)+1=2β−1. Line L10 writes t=ci+carry′β with carry′∈{0,1} and 0≤ci<β: if t≥β then ci=t−β≤β−1, else ci=t. Then
j≤i∑cjβj+carry′βi+1=j<i∑cjβj+tβi=j<i∑cjβj+carry⋅βi+(ai+bi)βi, which by (A) is ∑j≤i(aj+bj)βj. So (A) holds for i+1.
Termination. The loop runs m times. At its end, (A) for i=m says ∑j<mcjβj+carry⋅βm=mag(a)+mag(b). Line L11 appends the limb 1 exactly when carry is 1, so mag(c)=mag(a)+mag(b).
Normalized. If carry is 1, the top limb of c is 1. If carry is 0 and m≥1, then mag(c)≥mag(a)≥βm−1 by Fact 1, while ∑j<m−1cjβj≤βm−1−1; so cm−1=0. If m=0, then c is empty. □
Lemma 3 (SUB-MAG). For lists a and b of limbs with m=∣a∣≥∣b∣=n and mag(a)≥mag(b), SUB-MAG returns a normalized list c with mag(c)=mag(a)−mag(b).
Proof. Again let bi=0 for i≥n. The invariant of the loop of line L14 is
(S) at the start of step i, c0,…,ci−1 are limbs, borrow∈{0,1}, and ∑j<icjβj−borrow⋅βi=∑j<i(aj−bj)βj.
Initialization. Line L13 sets borrow to 0; both sides are 0 for i=0.
Maintenance. Line L15 gives t=ai−bi−borrow, so −β≤t≤β−1. Line L16 writes t=ci−borrow′β with borrow′∈{0,1} and 0≤ci<β: if t<0 then ci=t+β∈[0,β−1], else ci=t. The same computation as in Lemma 2, with −borrow in place of carry, gives (S) for i+1.
Termination. After m steps, mag(c)−borrow⋅βm=mag(a)−mag(b)≥0. Since mag(c)≤βm−1<βm, the borrow must be 0, and mag(c)=mag(a)−mag(b). Line L17 removes only zero limbs at the top, which do not change mag(c), and it stops with an empty list or a nonzero top limb, so c is normalized. □
Theorem (ADD). For normalized pairs x=(s,a) and y=(t,b), ADD(x,y) returns a normalized pair with the value val(x)+val(y).
Proof. Write σ(+)=1 and σ(−)=−1, so val(x)=σ(s)mag(a). ADD-MAG and SUB-MAG are called with the longer list first: ADD-MAG swaps its arguments when needed, and SUB-MAG is called only after CMP-MAG has shown that its first argument has the larger or equal magnitude, which by Fact 1 for normalized lists means at least as many limbs.
Case s=t. Line L2 returns (s,c) with mag(c)=mag(a)+mag(b) by Lemma 2, so the value is σ(s)(mag(a)+mag(b))=val(x)+val(y). The longer of a and b is a normalized list, so c is a normalized list by Lemma 2. If c is empty, then a and b are both empty, so s=t=+ by (N) for x, and the pair is normalized.
Case s=t. Then val(x)+val(y)=σ(s)(mag(a)−mag(b)). By Lemma 1, line L3 gets the sign c of mag(a)−mag(b). If c=0, the sum is 0, and line L4 returns (+,[]), which is normalized and has the value 0. If c>0, line L5 returns (s,d) with mag(d)=mag(a)−mag(b)>0 by Lemma 3; d is a normalized list and is not empty, so the pair is normalized, and its value is σ(s)(mag(a)−mag(b)), the sum. If c<0, line L6 returns (t,d) with mag(d)=mag(b)−mag(a)>0, and σ(t)(mag(b)−mag(a))=σ(s)(mag(a)−mag(b)) since σ(t)=−σ(s). □
Subtraction and negation. Negation maps (s,a) to (sˉ,a) for a nonempty and keeps (+,[]); the result is normalized and has the value −val(x). Then SUB(x,y) = ADD(x,−y) is correct by the theorem.
Lemma 4 (MUL). For normalized pairs, MUL returns a normalized pair with the value val(x)val(y).
Proof. If m=0 or n=0 the product is 0, and line M1 returns (+,[]). Otherwise the schoolbook multiplication proof shows that after lines M2 to M7 the list c of m+n limbs has mag(c)=mag(a)mag(b). By Fact 1, mag(a)mag(b)≥βm−1βn−1=βm+n−2, so the limbs cm+n−2 and cm+n−1 are not both zero: if both were zero, mag(c)≤βm+n−2−1. Hence removing one zero top limb at line M8 leaves a normalized nonempty list. The sign is + exactly when the signs agree, and σ(s)σ(t) is the sign of the product. □
Lemma 5 (DIV-LIMB). For a normalized pair (s,a) and a limb 0<d<β, DIV-LIMB returns a normalized pair (s′,q) and an r with mag(a)=mag(q)d+r and 0≤r<d.
Proof. Let k=∣a∣ and Pi=∑j≥iajβj−i, the number formed by the limbs ak−1,…,ai; so Pk=0, Pi=Pi+1β+ai and P0=mag(a). The invariant before the step with index i (from k−1 down) is Pi+1=∑j>iqjβj−i−1⋅d+r with 0≤r<d. It holds at the start with r=0 and no digits. In the step, u=rβ+ai satisfies 0≤u≤(d−1)β+β−1<dβ, so qi=⌊u/d⌋<β is a limb, and u=qid+r′ with 0≤r′<d. Then Pi=Pi+1β+ai=(∑j>iqjβj−i)d+u=(∑j≥iqjβj−i)d+r′, the invariant for i−1. After the step with i=0 this is the claim. Line D4 removes the zero top limbs and sets the sign to + for an empty quotient, so the pair is normalized. ■