Proofs: Grisu
These are the human proofs of Grisu, at full length.
A result certified by Grisu3 is the shortest and nearest decimal, and the fallback is exact full
This proof shows: correctness.
Setting. Binary64, finite, as decoded by L1. Let be the neighbors of (with for the largest finite number), , , and let be the rounding interval with ends and , closed when is even and open otherwise (ties to even). We prove: if grisu3(x) returns digits and an exponent , then lies strictly inside , so every reader that rounds to nearest maps to ; no number with fewer significant digits lies in the closed interval ; and is the multiple of in nearest to . Then we prove the fallback correct.
Lemma 1 (the boundaries are exact, L2). , and equals if is a power of two above the smallest normal and otherwise; all three numbers , , are represented exactly with significands below and a common exponent after the shifts of L2.
Proof. The spacing of floats around is on both sides, except below a power of two with , where it is ; the midpoints follow. The significands have at most binary digits, and normalizing to digits and shifting to the same exponent keeps .
Lemma 2 (scaling errors, L3 to L5). Let be the cached power and , where is the common binary exponent of the three products. Measure everything in units of , and let , , be the exact scaled values. Then the computed integers satisfy , and . Consequently and .
Proof. The table entry is with . For a 64-bit significand , differs from the exact by at most , and _times rounds to an integer with error at most . The sum is below . Then and .
So the scaled closed interval lies strictly inside the unsafe interval , and every point with lies strictly inside , since and .
Lemma 3 (digit generation, L6 and L7). Let the loop stop when the digits produced so far form the integer and the current position is , and let (the weight of the last digit in units). Then is the largest multiple of that is at most , , and for every coarser power with there is no multiple of in .
Proof. The integer part of is integrals, below , and its decimal digits are produced from the left; after each digit, rest is minus the truncation of to the current position, so the truncation is the largest multiple of the current that is at most . In the fractional phase, all of fractionals, unit, unsafe and the distance passed to _round_weed are multiplied by at each step, which is the same as measuring in units of after fractional digits, and the same statement holds. The loop continues while , that is, while the truncation is at most ; then no multiple of that lies in , because the largest one below is already not above . For powers coarser than the first digit, the only multiples at most are . It stops at the first position with , that is, . All quantities stay below : , , and in the fractional phase the loop only continues while , so .
Lemma 4 (fewest digits). No number with fewer significant digits than lies in .
Proof. Scaling by maps decimals to decimals with the same significant digits up to the power of ten, and to . Suppose in this interval has fewer significant digits than the accepted . If and have the same leading position, then is a multiple of a coarser power , which Lemma 3 excludes. If the leading position of is lower, then for the leading power of (in units), so lies in the interval between and , inside ; it is a multiple of , which is coarser than unless has one digit, and then cannot have fewer. Both cases contradict Lemma 3. A leading position of above that of is impossible, since by Lemma 3 applied to .
Lemma 5 (rounding, L8 to L10). If _round_weed returns true, the final candidate lies strictly inside and is the multiple of nearest to among those in , strictly nearer than any other.
Proof. Write and let be the current unit. The distance is passed in, so by Lemma 2, lies in the open interval with and . The loop of L8 replaces by while (i) , (ii) , and (iii) is above or at least as close to as (the two forms of the third condition are and ). Hence at the end of the loop, is either the initial candidate's successor, which exceeds , or a former candidate that is not closer to than , and therefore strictly farther than from every point below , in particular from . L9 returns false unless one of the conditions fails for : (i') , or (ii') , or (iii') is not strictly closer to than . In case (i'), and every smaller multiple is farther; in case (ii'), no smaller multiple is in ; in case (iii'), is at least as close to as , so strictly closer to every point above , in particular to . So no other multiple of in is as close to as . Finally, the test means ; in units of , Lemma 2 gives and , so .
Theorem. If grisu3(x) returns , then lies in the open interval , no number with fewer significant digits lies in , has nonzero first and last digits, and is the strictly nearest to among the multiples of in . In particular to_string agrees with any correct shortest-nearest printer whenever grisu3 succeeds.
Proof. Undo the scaling: the accepted corresponds to and . Lemmas 4 and 5 give the claims about the interval, the length and the nearest choice. The first digit is nonzero by construction. If the last digit were , would be a multiple of inside the interval, contradicting Lemma 4. The last digit never goes below in L8: a candidate whose last digit is is a multiple of , and by Lemma 3 none lies in , so such a candidate equals , condition (ii) stops the loop there, and the final test rejects it.
The fallback. exact_shortest computes with exact rationals and searches the powers downward from a power of ten above . For each , the multiples of nearest to are and the next one; is an interval containing , so it contains a multiple of if and only if it contains one of these two. The first for which one is inside is the coarsest, and by the argument of Lemma 4 the number chosen has the fewest significant digits; among the two candidates it takes the nearer, and the even one in a tie. As in the analysis of Dragon4, a shortest number that is not a multiple of can exist only if straddles a power of ten and contains a one-digit number below it, which needs a relative width of above , that is a subnormal with ; for these nine values the tests compare the output with Python's repr directly. So shortest(x) is always the shortest, nearest decimal, ties to even.