Algorithm Search⌘K

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, x>0x > 0 finite, x=f⋅2ex = f \cdot 2^{e} as decoded by L1. Let x±x^{\pm} be the neighbors of xx (with x+=21024x^{+} = 2^{1024} for the largest finite number), M+=(x+x+)/2M^{+} = (x + x^{+})/2, M−=(x−+x)/2M^{-} = (x^{-} + x)/2, and let RR be the rounding interval with ends M−M^{-} and M+M^{+}, closed when ff is even and open otherwise (ties to even). We prove: if grisu3(x) returns digits NN and an exponent tt, then y=N⋅10ty = N \cdot 10^{t} lies strictly inside (M−,M+)(M^{-}, M^{+}), so every reader that rounds to nearest maps yy to xx; no number with fewer significant digits lies in the closed interval [M−,M+][M^{-}, M^{+}]; and yy is the multiple of 10t10^{t} in RR nearest to xx. Then we prove the fallback correct.

Lemma 1 (the boundaries are exact, L2). (2f+1)2e−1=M+(2f + 1)2^{e - 1} = M^{+}, and M−M^{-} equals (4f−1)2e−2(4f - 1) 2^{e - 2} if xx is a power of two above the smallest normal and (2f−1)2e−1(2f - 1)2^{e - 1} otherwise; all three numbers xx, M+M^{+}, M−M^{-} are represented exactly with significands below 2642^{64} and a common exponent after the shifts of L2.

Proof. The spacing of floats around xx is 2e2^{e} on both sides, except below a power of two 252⋅2e2^{52} \cdot 2^{e} with e>−1074e > -1074, where it is 2e−12^{e - 1}; the midpoints follow. The significands have at most 5555 binary digits, and normalizing M+M^{+} to 6464 digits and shifting M−M^{-} to the same exponent keeps M−<M+<264⋅2exponentM^{-} < M^{+} < 2^{64} \cdot 2^{\text{exponent}}. □\square

Lemma 2 (scaling errors, L3 to L5). Let 10K10^{K} be the cached power and 1=2−e2\mathbf{1} = 2^{-e_2}, where e2∈[−60,−32]e_2 \in [-60, -32] is the common binary exponent of the three products. Measure everything in units of 2e22^{e_2}, and let w∗=x10K2−e2w^{*} = x 10^{K} 2^{-e_2}, h∗=M+10K2−e2h^{*} = M^{+} 10^{K} 2^{-e_2}, ℓ∗=M−10K2−e2\ell^{*} = M^{-} 10^{K} 2^{-e_2} be the exact scaled values. Then the computed integers satisfy ∣w−w∗∣<1|w - w^{*}| < 1, ∣high−h∗∣<1|\mathit{high} - h^{*}| < 1 and ∣low−ℓ∗∣<1|\mathit{low} - \ell^{*}| < 1. Consequently too_low<ℓ∗\mathit{too\_low} < \ell^{*} and h∗<too_highh^{*} < \mathit{too\_high}.

Proof. The table entry is cf=10K2−ce(1+error)c_f = 10^{K} 2^{-c_e}(1 + \text{error}) with ∣cf−10K2−ce∣≤12|c_f - 10^{K}2^{-c_e}| \le \tfrac12. For a 64-bit significand aa, acf2−64a c_f 2^{-64} differs from the exact a⋅10K2−ce−64a \cdot 10^{K} 2^{-c_e - 64} by at most a⋅12⋅2−64<12a \cdot \tfrac12 \cdot 2^{-64} < \tfrac12, and _times rounds acf2−64a c_f 2^{-64} to an integer with error at most 12\tfrac12. The sum is below 11. Then too_low=low−1<ℓ∗\mathit{too\_low} = \mathit{low} - 1 < \ell^{*} and too_high=high+1>h∗\mathit{too\_high} = \mathit{high} + 1 > h^{*}. □\square

So the scaled closed interval [ℓ∗,h∗][\ell^{*}, h^{*}] lies strictly inside the unsafe interval (too_low,too_high)(\mathit{too\_low}, \mathit{too\_high}), and every point cc with too_low+2≤c≤too_high−2\mathit{too\_low} + 2 \le c \le \mathit{too\_high} - 2 lies strictly inside (ℓ∗,h∗)(\ell^{*}, h^{*}), since ℓ∗<low+1=too_low+2\ell^{*} < \mathit{low} + 1 = \mathit{too\_low} + 2 and h∗>high−1=too_high−2h^{*} > \mathit{high} - 1 = \mathit{too\_high} - 2.

Lemma 3 (digit generation, L6 and L7). Let the loop stop when the digits produced so far form the integer DD and the current position is 10κ10^{\kappa}, and let Δ=10κ1\Delta = 10^{\kappa}\mathbf{1} (the weight of the last digit in units). Then c=DΔc = D\Delta is the largest multiple of Δ\Delta that is at most too_high\mathit{too\_high}, c>too_lowc > \mathit{too\_low}, and for every coarser power Δ′=10κ′1\Delta' = 10^{\kappa'}\mathbf{1} with κ′>κ\kappa' > \kappa there is no multiple of Δ′\Delta' in (too_low,too_high](\mathit{too\_low}, \mathit{too\_high}].

Proof. The integer part of too_high/1\mathit{too\_high}/\mathbf{1} is integrals, below 2322^{32}, and its decimal digits are produced from the left; after each digit, rest is too_high\mathit{too\_high} minus the truncation of too_high\mathit{too\_high} to the current position, so the truncation is the largest multiple of the current Δ\Delta that is at most too_high\mathit{too\_high}. In the fractional phase, all of fractionals, unit, unsafe and the distance passed to _round_weed are multiplied by 1010 at each step, which is the same as measuring in units of 2e2/10j2^{e_2}/10^{j} after jj fractional digits, and the same statement holds. The loop continues while rest≥unsafe=too_high−too_low\mathit{rest} \ge \mathit{unsafe} = \mathit{too\_high} - \mathit{too\_low}, that is, while the truncation is at most too_low\mathit{too\_low}; then no multiple of that Δ′\Delta' lies in (too_low,too_high](\mathit{too\_low}, \mathit{too\_high}], because the largest one below too_high\mathit{too\_high} is already not above too_low\mathit{too\_low}. For powers coarser than the first digit, the only multiples at most too_high\mathit{too\_high} are ≤0<too_low\le 0 < \mathit{too\_low}. It stops at the first position with rest<unsafe\mathit{rest} < \mathit{unsafe}, that is, c>too_lowc > \mathit{too\_low}. All quantities stay below 2642^{64}: too_high<264\mathit{too\_high} < 2^{64}, 1≤260\mathbf{1} \le 2^{60}, and in the fractional phase the loop only continues while unsafe≤fractionals<1\mathit{unsafe} \le \mathit{fractionals} < \mathbf{1}, so 10 unsafe<26410\,\mathit{unsafe} < 2^{64}. □\square

Lemma 4 (fewest digits). No number with fewer significant digits than NN lies in [M−,M+][M^{-}, M^{+}].

Proof. Scaling by 10K2−e210^{K} 2^{-e_2} maps decimals to decimals with the same significant digits up to the power of ten, and [M−,M+][M^{-}, M^{+}] to [ℓ∗,h∗]⊂(too_low,too_high)[\ell^{*}, h^{*}] \subset (\mathit{too\_low}, \mathit{too\_high}). Suppose zz in this interval has fewer significant digits than the accepted cc. If zz and cc have the same leading position, then zz is a multiple of a coarser power Δ′\Delta', which Lemma 3 excludes. If the leading position of zz is lower, then z<10L≤cz < 10^{L} \le c for the leading power 10L10^{L} of cc (in units), so 10L10^{L} lies in the interval between zz and cc, inside (too_low,too_high)(\mathit{too\_low}, \mathit{too\_high}); it is a multiple of 10L10^{L}, which is coarser than Δ\Delta unless cc has one digit, and then zz cannot have fewer. Both cases contradict Lemma 3. A leading position of zz above that of cc is impossible, since z<too_high<10L+1z < \mathit{too\_high} < 10^{L + 1} by Lemma 3 applied to Δ′=10L+1\Delta' = 10^{L+1}. □\square

Lemma 5 (rounding, L8 to L10). If _round_weed returns true, the final candidate cc lies strictly inside (ℓ∗,h∗)(\ell^{*}, h^{*}) and is the multiple of Δ\Delta nearest to w∗w^{*} among those in [ℓ∗,h∗][\ell^{*}, h^{*}], strictly nearer than any other.

Proof. Write c=too_high−restc = \mathit{too\_high} - \mathit{rest} and let uu be the current unit. The distance too_high−w\mathit{too\_high} - w is passed in, so by Lemma 2, w∗w^{*} lies in the open interval (wlo,whi)(w_{\mathrm{lo}}, w_{\mathrm{hi}}) with whi=too_high−small=w+uw_{\mathrm{hi}} = \mathit{too\_high} - \mathit{small} = w + u and wlo=too_high−big=w−uw_{\mathrm{lo}} = \mathit{too\_high} - \mathit{big} = w - u. The loop of L8 replaces cc by c−Δc - \Delta while (i) c>whic > w_{\mathrm{hi}}, (ii) c−Δ≥too_lowc - \Delta \ge \mathit{too\_low}, and (iii) c−Δc - \Delta is above whiw_{\mathrm{hi}} or at least as close to whiw_{\mathrm{hi}} as cc (the two forms of the third condition are rest+Δ<small\mathit{rest} + \Delta < \mathit{small} and c−whi≥whi−(c−Δ)c - w_{\mathrm{hi}} \ge w_{\mathrm{hi}} - (c - \Delta)). Hence at the end of the loop, c+Δc + \Delta is either the initial candidate's successor, which exceeds too_high>h∗\mathit{too\_high} > h^{*}, or a former candidate that is not closer to whiw_{\mathrm{hi}} than cc, and therefore strictly farther than cc from every point below whiw_{\mathrm{hi}}, in particular from w∗w^{*}. L9 returns false unless one of the conditions fails for wlow_{\mathrm{lo}}: (i') c≤wloc \le w_{\mathrm{lo}}, or (ii') c−Δ<too_low<ℓ∗c - \Delta < \mathit{too\_low} < \ell^{*}, or (iii') c−Δc - \Delta is not strictly closer to wlow_{\mathrm{lo}} than cc. In case (i'), c<w∗c < w^{*} and every smaller multiple is farther; in case (ii'), no smaller multiple is in [ℓ∗,h∗][\ell^{*}, h^{*}]; in case (iii'), cc is at least as close to wlow_{\mathrm{lo}} as c−Δc - \Delta, so strictly closer to every point above wlow_{\mathrm{lo}}, in particular to w∗w^{*}. So no other multiple of Δ\Delta in [ℓ∗,h∗][\ell^{*}, h^{*}] is as close to w∗w^{*} as cc. Finally, the test 2u≤rest≤unsafe−4u2u \le \mathit{rest} \le \mathit{unsafe} - 4u means too_low+4u≤c≤too_high−2u\mathit{too\_low} + 4u \le c \le \mathit{too\_high} - 2u; in units of uu, Lemma 2 gives ℓ∗<too_low+2u\ell^{*} < \mathit{too\_low} + 2u and h∗>too_high−2uh^{*} > \mathit{too\_high} - 2u, so ℓ∗<c<h∗\ell^{*} < c < h^{*}. □\square

Theorem. If grisu3(x) returns (N,t)(N, t), then y=N10ty = N 10^{t} lies in the open interval (M−,M+)(M^{-}, M^{+}), no number with fewer significant digits lies in [M−,M+][M^{-}, M^{+}], yy has nonzero first and last digits, and yy is the strictly nearest to xx among the multiples of 10t10^{t} in RR. In particular to_string agrees with any correct shortest-nearest printer whenever grisu3 succeeds.

Proof. Undo the scaling: the accepted cc corresponds to y=N10κ−Ky = N 10^{\kappa - K} and t=κ−Kt = \kappa - K. 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 00, yy would be a multiple of 10t+110^{t + 1} inside the interval, contradicting Lemma 4. The last digit never goes below 00 in L8: a candidate whose last digit is 00 is a multiple of 10Δ10\Delta, and by Lemma 3 none lies in (too_low,too_high](\mathit{too\_low}, \mathit{too\_high}], so such a candidate equals too_low\mathit{too\_low}, condition (ii) stops the loop there, and the final test rejects it. ■\blacksquare

The fallback. exact_shortest computes RR with exact rationals and searches the powers 10t10^{t} downward from a power of ten above M+M^{+}. For each tt, the multiples of 10t10^{t} nearest to xx are ⌊x/10t⌋10t\lfloor x/10^{t}\rfloor 10^{t} and the next one; RR is an interval containing xx, so it contains a multiple of 10t10^{t} if and only if it contains one of these two. The first tt 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 10t10^{t} can exist only if RR straddles a power of ten and contains a one-digit number below it, which needs a relative width of RR above 10%10\%, that is a subnormal m2−1074m 2^{-1074} with m≤9m \le 9; 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. ■\blacksquare

Back to Grisu