Limb arrays: addition, subtraction, and multiplication #
The carry-propagating loops of multiple-precision integer arithmetic over LimbArray. Each loop
recurses on the number of limbs still to process and writes its result with
Array.setIfInBounds. The 32-bit limbs leave room for the addition and multiplication
intermediates in UInt64.
carryLoopadds one word at a limb position and propagates the carry upward. It is the primitive behindaddWordAt,addAt, and the increment used by rounding.addandsubare the schoolbook sum and difference with an incoming carry or borrow;subassumes its result is nonnegative and the incoming borrow is at most one.mulis the schoolbook product; each row adds one limb of the left operand times the right operand at the row's offset.
Arithmetic.Proof states each kernel's effect on toNat, including the required capacity,
borrow, and accumulator invariants.
Carry propagation #
Add w * 2^k to the array.
The word is split at the limb boundary containing bit k; both halves are added with carry
propagation. The result is meaningful when the sum still fits the stored limbs.
Instances For
Addition and subtraction #
The sum of two arrays and an incoming carry, in one limb more than the wider operand.
Instances For
The difference a - b - borrow, in as many limbs as the wider operand.
The result is exact when borrow ≤ 1 and b + borrow ≤ a; Arithmetic.Proof.toNat_sub
states that contract.
Instances For
Multiplication #
Add m times count limbs of b, starting at limb j, into out at offset offset + j.
Store the final carry at offset + j + count; that slot must initially be zero.
Every intermediate m * b_j + out_(offset + j) + carry is below 2^64.
Instances For
The schoolbook product, in a.size + b.size limbs.