I’ve run into something odd, here, and I’m at a loss — I have a feeling this has something to do with floating precision, but I’m surprised Python would not display the approximation error, if so.
I’m working on Project Euler problem 62. As a simple test (I’ve since solved using a different approach), I had a is_cube which I intended to check if a number cubes perfectly. So, to try the sample given, I did this:
def is_cube(i):
c = i ** (1./3)
print "c is", c
When I ran this with i = 41063625, the expected output was:
c is 345.0
Here’s where the unexpected happened:
def is_cube(i):
c = i ** (1./3)
print "c is", int(c)
Suddenly, I had this:
c is 344
The value c does not compare against my 345.0 literal, either — c < 345.0 is True.
Is there precision in this number that Python is not showing me? I seem to recall reading about a change to make floats appear more sane when printed; is this it? What is different about these two cases?
>>> def is_cube(i):
... c = i ** (1./3)
... print "c is", c
...
>>> is_cube(41063625)
c is 345.0
>>> 41063625 ** (1./3)
344.99999999999989
Edit: Still had the window open and did this:
>>> print _
345.0
Now I’m starting to think I should have known all along that print was to blame.
This is using
c.__str__()(aka.str(c)) :This is using
c.__repr__()(aka.repr(c)) :IIRC,
__str__truncates to 10 decimals, whereas__repr__goes further. To get the same behavior as in the Python shell, you could do :The change you’re talking about in your message is only about Python 3.1 and do not alter the precision of the output : Gay’s algorithm which is used for
__repr__on floating point numbers in Python 3.1 will, when given two representation choices which yields the same floating point value (like0.2and0.2000000000000001), choose the shortest one.