This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: Identical floats print inconsistently
Type: Stage:
Components: None Versions:
process
Status: closed Resolution: not a bug
Dependencies: Superseder:
Assigned To: Nosy List: georg.brandl, gihon, tim.peters
Priority: normal Keywords:

Created on 2006-08-04 20:07 by gihon, last changed 2022-04-11 14:56 by admin. This issue is now closed.

Messages (4)
msg29447 - (view) Author: Marc W. Abel (gihon) Date: 2006-08-04 20:07
Hi, and thank you.

Many bugs relating to this have been submitted by
others over a period of years, and these have generally
been closed with "not a bug" responses.  I'll do my
best to explain the problem clearly enough.

The following session prints a single variable three
ways, with two different results:

-----------

[me@localhost current]$ python
Python 2.4.1 (#1, May 16 2005, 15:19:29)
[GCC 4.0.0 20050512 (Red Hat 4.0.0-5)] on linux2
Type "help", "copyright", "credits" or "license" for
more information.
>>> a = round(1./7, 3)
>>> print a
0.143
>>> print (a,)
(0.14299999999999999,)
>>> print (a,)[0]
0.143
>>>

-----------

I'm fully informed about IEEE floating point
representations in binary, but the limitations of data
type are not causing the difference in output.  The
interpreter is using different rules to print this
float, depending on whether it's a straight float or
part of some other structure (in this example, a tuple).

Once the interpreter recurses to a depth where it's
clearly going to print a float, whatever rule is
selected needs to be consistently applied.  This means
calling the same string formatting code with the same
inputs.

Marc
msg29448 - (view) Author: Georg Brandl (georg.brandl) * (Python committer) Date: 2006-08-04 20:14
Logged In: YES 
user_id=849994

Sorry, but this is another "not a bug".

"print tuple" invokes tuple.__repr__() (because there is no
separate __str__) which invokes repr(item) on each tuple
item, while "print item" invokes str(item). For floats, this
distinction results in a different rounding precision.
msg29449 - (view) Author: Tim Peters (tim.peters) * (Python committer) Date: 2006-08-04 21:24
Logged In: YES 
user_id=31435

gbrandl is correct that the differences here are entirely
due to the difference between float's __repr__ and __str__
methods.  The reasons they /are/ different for floats are
explained in the Tutorial's appendix on floating-point issues.

It may be considered unfortunate that tuple.__repr__ is the
same as tuple.__str__, and that both "pass repr down" to
containees, but the reason for that has to do with the
difference between str.__repr__ and str.__str__.  If
str(tuple) "passed str down" to containees, then, e.g.,

    print ("a, bc", "de f,", "gh), i")

would display the incomprehensibly confused:

    (a, bc, de f,, gh), i)

IOW, it's actually the difference in what string types do
that /drives/ the general decision that c.__str__ is the
same as c.__repr__ for all objects `c` of container types,
and that both "pass repr down" to containees.

Alas, that's not always what people using strings want
either :-)
msg29450 - (view) Author: Marc W. Abel (gihon) Date: 2006-08-05 06:24
Logged In: YES 
user_id=789149

Hi Tim and Georg,

Thanks for your kind replies.  I've followed up with feature
request 1534942, suggesting that print pass down __strep__,
which passes itself down.  __strep__ prints floats with
__str__ and everything else with __rep__.

Enjoy the weekend!  I'll be writing a ray tracer....

Marc
History
Date User Action Args
2022-04-11 14:56:19adminsetgithub: 43779
2006-08-04 20:07:00gihoncreate