Subtraction is addition's mirror - a borrow instead of a carry - and its edge is the opposite too, since the result can shrink and lose its top limbs. Today you subtract the smaller magnitude from the larger.
Subtract a smaller magnitude from a larger one with borrows, normalizing away any leading zero limbs.
Subtraction walks the limbs the same way addition does, but when a limb of a is
smaller than the corresponding limb of b (plus any incoming borrow) you cannot go
negative in a single limb - so you borrow one base’s worth from the next limb up,
add 1000000000 to the current difference, and remember to pay it back next
iteration. Because we always subtract the smaller magnitude from the larger (that is
what cmpMag was for), the final borrow is guaranteed to be zero.
The mirror-image edge to addition’s growing carry is a shrinking result.
1000000000000000000 - 1 borrows all the way down and leaves the top limb as zero,
so after normalize the number is two limbs, not three. A subtraction can even
empty the magnitude entirely (5 - 5), which normalize turns into canonical zero.
Running the raw result through normalize is what keeps that invariant intact.
// precondition: a >= b by magnitudefunc subMag(a, b mag) mag {var out magvar borrow int64for i := range a {diff := int64(a[i]) - borrowif i < len(b) { diff -= int64(b[i]) }if diff < 0 { diff += Base; borrow = 1 } else { borrow = 0 }out = append(out, uint32(diff))}return out.normalize()}