Proofs: Clinger's correct decimal input
These are the human proofs of Clinger's correct decimal input, at full length.
Clinger's fast path and AlgorithmM return the correctly rounded binary64 number full
This proof shows: correctness.
Setting. Binary64: precision , the smallest subnormal with , the largest finite number with . is rounding to nearest, ties to even, with the overflow rule of IEEE 754-2019 (Clause 7.4): the result is when the value rounded with an unbounded exponent range is at least . The input is a pair of integers and ; the goal is . Two facts about the format are used. (F1) If , then the floats in are exactly the integer multiples of in that interval (for this is the binade of exponent and its upper end). (F2) The floats in are exactly the integer multiples of in that interval (the subnormals, zero and the smallest normal).
Lemma 1 (fast path, lines L2 and L3). If and , then L3 returns .
Proof. is an integer below , so exactly. For , and , so is a binary64 number and the table entry is exact. IEEE 754 multiplication and division return the correctly rounded value of the exact product or quotient of their operands (Clause 5.4.1), so the single operation returns or . No overflow or underflow occurs: and .
Lemma 2 (scale, lines L5 and L6). Let and be integers, and their lengths in binary, and . After L6, .
Proof. From and we get , so with (L5), . L6 computes . If it is at least , then and after we have . Otherwise already, since .
Lemma 3 (the neighbors of ). After L7, set . Then and are consecutive numbers of the binary64 grid with an unbounded exponent range, and .
Proof. The inequality holds by the definition of the floor. If L7 did not change , then and by Lemma 2, so both points lie in , and by (F1), applied to the format without an upper exponent limit, the grid points there are exactly the multiples of . If L7 raised to , then by Lemma 2 the old scale gives , so and both points lie in , where by (F2) the floats are exactly the multiples of . In both cases there is no grid point strictly between them.
Lemma 4 (rounding, lines L8 and L9). After L9, is the grid point nearest to , with ties broken to the even significand.
Proof. L8 divides the integers and with , so is the quotient and with . By Lemma 3 the nearest grid point is if , that is , and if . If , then is the midpoint, and IEEE ties to even picks the neighbor whose integral significand is even. For (normal case) and for (subnormal case) the integral significand of is itself; if , the upper neighbor is the power of two with even significand , and is odd; if in the subnormal case, the upper neighbor is , whose significand is even, and is odd. In every case "the even one" is when is even and otherwise, which is the test of L9. The carry step rewrites as without changing the value.
Theorem. For integers and , clinger_read(f, e) returns , including on overflow and subnormal or zero results on underflow. With the sign applied afterwards, read_float returns the correctly rounded value of any decimal string it accepts, since .
Proof. If L2 holds, Lemma 1 applies. Otherwise L4 forms and with exactly: and for , and for . By Lemma 4, after L9 the value is the rounding of to the binary64 grid with an unbounded exponent range, with after the carry step and . If , then is a finite float, and ldexp returns it exactly. If , then (the case occurs only with ), so , and the IEEE overflow rule for rounding to nearest gives , which L10 returns.
Remarks. The proof uses only exact integer arithmetic in AlgorithmM, so it holds for any number of digits and any exponent; the cost, not the correctness, grows with them. Lemma 1 is the only place where floating-point operations are used, and it needs the processor to round binary64 operations once, to binary64 precision; on x87 hardware with 64-bit internal precision the fast path can round twice (double rounding).