Is there precision in this number that Python isn't showing me?
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 开发者_Go百科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)
) :
print "c is", c
This is using c.__repr__()
(aka. repr(c)
) :
>>> c # In the Python shell
IIRC, __str__
truncates to 10 decimals, whereas __repr__
goes further. To get the same behavior as in the Python shell, you could do :
print repr(c)
# Or
print "%r" % c
# Or
print "%.16f" % c
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 (like 0.2
and 0.2000000000000001
), choose the shortest one.
print "c is", int(c)
The integer conversion will simply drop anything after the decimal point so even if you have 344.99999999999989 it will always round down. you could use old school print %
print'c is %5.0f' % c
or you could use round if you want an integer
print'c is %d' % round(c,0)
Also you might be interested in other solutions for the cube root problem here
精彩评论