[Python-Dev] Expert floats

Ka-Ping Yee python-dev at zesty.ca
Tue Mar 30 19:41:40 EST 2004


On Tue, 30 Mar 2004, Tim Peters wrote:
> repr(float) used to round to 12 significant digits (same as str() does
> ow  -- repr(float) and str(float) used to be identical).  So the problem was
> real, and so was the fix.

All right.  Maybe we can make some progress.  I agree that round-to-12
was a real problem.  But i think we are talking about two different use
cases: compiling to disk and displaying on screen.

I think we can satisfy both desires.

If i understand you right, your primary aim is to make sure the marshalled
form of any floating-point number yields the closest possible binary
approximation to the machine value on the original platform, even when
that representation is used on a different platform.  (Is that correct?
Perhaps it's best if you clarify -- exactly what is the invariant you
want to maintain, and what changes [in platform or otherwise] do you want
the representation to withstand?)

That doesn't have to be part of repr()'s contract.  (In fact, i would
argue that already repr() makes no such promise.)  repr() is about
providing a representation for humans.

Can we agree on maximal precision for marshalling, and shortest-
accurate precision for repr, so we can both be happy?

(By shortest-accurate i mean "the shortest representation that converts
to the same machine number".  I believe this is exactly what Andrew
described as Scheme's method.  If you are very concerned about this being
a complex and/or slow operation, a fine compromise would be a "try-12"
algorithm: if %.12g is accurate then use it, and otherwise use %.17g.
This is simple, easy to implement, produces reasonable results in most
cases, and has a small bound on CPU cost.)

    def try_12(x):
        rep = '%.12g' % x
        if float(rep) == x: return rep
        return '%.17g' % x

    def shortest_accurate(x):
        for places in range(17):
            fmt = '%.' + str(places) + 'g'
            rep = fmt % x
            if float(rep) == x: return rep
        return '%.17g' % x


-- ?!ng



More information about the Python-Dev mailing list