[issue1580] Use shorter float repr when possible

Tim Peters report at bugs.python.org
Tue Dec 11 21:26:45 CET 2007

Tim Peters added the comment:

> I take it your position is that this can never be done 100% correctly

No.  David Gay's code is believed to be 100% correctly-rounded and is
also reasonably fast in most cases.  I don't know of any other "open"
string<->float code that achieves both (& expect that's why glibc
adopted Gay's code as its base).  I don't know anything about Tcl's
code here, except that, unlike Gay's code, it appears that Tcl's code
also tries to cater to non-754 platforms.  It's also easy to be 100%
correct if you don't care about speed (but that's factors of 1000s
slower than Gay's code).

If you care about guaranteeing eval(repr(x)) == x for binary floats,
sorry, there's no way to do it that satisfies all of {cheap, easy,
fast, correct}.  If you don't care about guaranteeing eval(repr(x)) ==
x, then it's dead easy to do any number of "wrong" things instead.
For example, much easier and faster than anything discussed here would
be to use the float str() implementation instead.  "Produce the
shortest possible output that reproduces the same input" is a
genuinely difficult task (for both output and input) when speed
matters, but it's not really what people are asking for when they see
0.10000000000000001.  They would be just as happy with str(x)'s output
instead:  it's not people who know a lot about floats who are asking
to begin with, it's people who don't know much at all.

It's not a coincidence that the whole idea of "shortest possible
output" came from the Scheme world ;-)  That is, "formally correct at
any price".

> so it shouldn't go in?

What shouldn't go in is something that doesn't solve "the problem",
whatever that's thought to be today.  Changing repr() to do
shortest-possible output is not, by itself, a solution /if/ the
problem is thought to be "getting rid of lots of zeroes or nines while
preserving eval(repr(x)) == x".  Slows things down yet isn't enough to
guarantee eval(repr(x)) == x.  This is just going in circles.

> That's disappointing, because the stream of complaints that "round is broken" won't stop (we
> had two of these in the bug tracker just this month).

I don't care about complaints from people who use binary floating
point without understanding it; they should use the decimal module
instead if they're unwilling or unable to learn.  Or give up on
eval(repr(x)) == x for binary floats and then it's all much easier --
although people using binary floats naively will get burned by
something subtler then.

A sufficient response to "round() is broken" complaints is to point to
the Tutorial appendix that specifically discusses "round() is broken"

Tracker <report at bugs.python.org>

More information about the Python-bugs-list mailing list