Why does str of float return more numbers in Python 3 than Python 2

  • 2020-12-18 01:51:20
  • OfStack

In Python 2.7, the repr of 1 float returns the nearest 107 decimal digits; This is enough to accurately identify every possible IEEE floating-point value. str for floating point numbers works similarly, except that it limits the result to 12 digits; For most purposes, this is a more reasonable result and frees you from the slight difference between base 2 and base 10 representations.

Python 2 demo: http: / / ideone com/OKJtxv


print str(1.4*1.5)
2.1
print repr(1.4*1.5)
2.0999999999999996

In Python 3.2, str and repr return the same thing.

Python 3 shows: http: / / ideone com/oAKRsb


print(str(1.4*1.5))
2.0999999999999996
print(repr(1.4*1.5))
2.0999999999999996

Is there PEP describing the change or any other statement for which someone is responsible?

No, there is no PEP. There is 1 issue in the error tracker and 1 associated discussion in the Python developers mailing list

While I am responsible for proposing and implementing change, I cannot say that it was my idea: it came about during the dialogue between EuroPython 2010 and Guido.

1 Some more details: as already mentioned in the comments,Python 3.1 introduced a new algorithm for string repr of float (it was later reprinted to the Python 2 series so that it also appeared in Python 2.7). As a result of this new algorithm, the "short" decimal number typed at the prompt has a corresponding shorter representation. This eliminates one of the existing reasons for the difference between str and repr, and allows the same algorithm to be used for str and repr. So for Python 3.2, str and repr are the same as discussed above. As to why: it makes the language become smaller, clean, and when the output string, it will be deleted 12 digit randomly choice. (before 2.7 Python version for repr number choice is not arbitrary, by the way 1: under two different IEEE binary64 754 floating point Numbers will be converted to decimal has different said, 17 valid number, 17 is the smallest integer with this property.)

In addition to simplicity, there are a few less obvious benefits. One aspect of the repr versus str distinction that has confused users in the past is that repr is used automatically for containers. So for example in Python 2.7:


>>> x = 1.4 * 1.5
>>> print x
2.1
>>> print [x]
[2.0999999999999996]

I am sure there is at least one StackOverflow question asking about this phenomenon: here is one such and another are closer to one. Through the simplification introduced in Python 3.2, we obtain:


>>> x = 1.4 * 1.5
>>> print(x)
2.0999999999999996
>>> print([x])
[2.0999999999999996]

This is at least one more.

If you really want to be able to hide inaccuracies, the correct approach remains the same: use the string format to precisely control the output format.


>>> print("{:.12g}".format(x))
2.1

I wish I could explain some of the reasons behind this change. I would not argue that this is universally beneficial: as you pointed out, the old str had the convenient side effect of hiding imprecision. But in my opinion (biased, of course), it does help remove some surprises from the language.

conclusion


Related articles: