[Serhiy Storchaka]
> This is not the only difference between '.17g' and repr().
>
> >>> '%.17g' % 1.23456789
> '1.2345678899999999'
> >>> format(1.23456789, '.17g')
> '1.2345678899999999'
> >>> repr(1.23456789)
> '1.23456789'

More amazingly ;-), repr() isn't even always the same as a %g format
specifying exactly the same number of digits as repr() produces.

That's because repr(x) currently returns the shortest string such that
eval(repr(x)) == x, but %g rounds correctly to the given number of
digits.  Not always the same thing!

>>> x = 2.0 ** 89
>>> print(repr(x))
6.189700196426902e+26
>>> print("%.16g" % x) # repr produced 16 digits
6.189700196426901e+26

The repr() output is NOT correctly rounded.  To see which one is
correctly rounded, here's an easy way:

>>> import decimal
>>> decimal.Decimal(x)
Decimal('618970019642690137449562112')

The "37449562112" is rounded off, and is less than half a unit in the
last place, so correct rounding truncates the last digit to 1.

But there is no string with 16 digits other than the incorrectly
rounded one repr() returns that gives x back.  In particular, the
correctly rounded 16 digit string does not:

>>> 6.189700196426901e+26 # 16-digit correctly rounded fails
6.189700196426901e+26
>>> x == _
False

To my mind it's idiotic(*) that "shortest string" requires incorrect
rounding in some cases.

In Python's history, eval(repr(x)) == x is something that was always
intended, so long as the writing and reading was done by the same
Python instance on the same machine.  Maybe it's time to document that
;-)

But CPython goes far beyond that now, also supplying correct rounding,
_except_ for repr's output, where - for reasons already illustrated -
"correct rounding" and "shortest" can't always both be satisfied.

(*) What wouldn't be idiotic?  For repr(x) to return the shortest
_correctly rounded_ string such that eval(repr(x)) == x.  In the
example, that would require repr(x) to produce a 17-digit output (and
17 is the most that's ever needed for a Python float on boxes with
IEEE doubles).  But "shortest string" was taken ultra literally by the
people who first worked out routines capable of doing that, so has
become a de facto standard now.
_______________________________________________
Python-Dev mailing list -- python-dev@python.org
To unsubscribe send an email to python-dev-le...@python.org
https://mail.python.org/mailman3/lists/python-dev.python.org/
Message archived at 
https://mail.python.org/archives/list/python-dev@python.org/message/F3BOGGTGJPZS3RR7FKG7YE6GYADHYI76/
Code of Conduct: http://python.org/psf/codeofconduct/

Reply via email to