Proofs: Kulisch accumulator
These are the human proofs of Kulisch accumulator, at full length.
The Kulisch accumulator holds the exact sum and rounds it correctly full
This proof shows: correctness.
Setting. binary64. Every finite float is with integers and , and . The register is limbs of 64 bits, bits, holding in two's complement, that is, the limbs encode and is read as the representative in . Write .
Lemma 1 (terms are integers on the grid). For finite floats and , is an integer with .
Proof. with , so is an integer. And .
Lemma 2 (one addition). Lines L1 to L5 replace the limbs encoding by limbs encoding .
Proof. Line L3 writes with and . The loop of L4 and L5 is schoolbook addition (or subtraction) in base starting at limb : after processing limb , the limbs and the pending carry represent the correct partial sum, by the usual induction on limbs. It stops when the remaining chunk and the carry are both zero, at which point the higher limbs are unchanged and correct; or at the top limb, where dropping the final carry or borrow is reduction modulo . Subtraction modulo is addition of .
Theorem 1 (exactness). If terms have been added (each a product, or a float times 1), then the register holds , so is the exact sum.
Proof. By Lemma 2 the limbs encode . By Lemma 1, , so the sum is itself the two's complement representative.
Theorem 2 (rounding). ROUND returns the binary64 number nearest to , ties to even, with overflow to when that number would reach .
Proof. Let with bit length , so and the leading bit of has exponent . If (normal range), the binary64 numbers in that binade are the multiples of , that is, must be rounded to a multiple of . If the leading exponent is below (subnormal range), the representable numbers are the multiples of , that is, must be rounded to a multiple of . Line L7 takes , which is the larger of the two exponents and hence the correct quantum in both cases (the normal case has exactly when ). If , then is already a multiple of the quantum (this cannot happen with , since , but the code allows it). Otherwise, write with ; the two neighbours are and , the midpoint is at , and line L8 chooses iff , or and is odd. That is round to nearest, ties to even. A carry from to moves the result to the next binade, where it is still representable as . Finally, the rounded value is at least exactly when 's bit length plus exceeds 1024, the test of line L9, and IEEE 754 round to nearest then returns . Since and the scaling is by a power of two within range, ldexp is exact. The sign is applied last, which is correct because round to nearest, ties to even, is symmetric.
Special values. Inputs that are not finite never reach the register. The flags implement the IEEE rules for a sum: any NaN, or both infinities, gives NaN; otherwise any infinity gives that infinity. A product with a non-finite factor is formed in floating point first, so sets the NaN flag.