[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/