Issue 7010: Rounding when converting float tuple to str (original) (raw)

Created on 2009-09-28 07:43 by scientist47, last changed 2022-04-11 14:56 by admin. This issue is now closed.

Messages (6)
msg93193 - (view) Author: Per Rosengren (scientist47) Date: 2009-09-28 07:43
When a floating point value is stored, the actual value stored is something at most some small number eps larger or smaller than the original value. Python knows this, so if it stores 0.1, and then prints the stored value, it rounds off decimals less significant than eps. For some reason, if it prints a tuple with the same value, it doesn't do the rounding properly. This behavior is incorrect, and very annoying for instance when printing manually entered constants in tuples. '''Shows that floats in tuples are not rounded like floats. >>> print(.1) 0.1 >>> print((.1,)) (0.10000000000000001,) ''' import doctest doctest.testmod(verbose=True)
msg93195 - (view) Author: Eric V. Smith (eric.smith) * (Python committer) Date: 2009-09-28 08:55
What OS, processor, and Python version are you running this code on? From your example, it's Python 3.x. 3.1 has a completely rewritten float->decimal conversion system, and I get different results. >>> print(.1) 0.1 >>> print((.1,)) (0.1,) >>> For 2.6 and 3.0, you'll get the old behavior, and this won't change. Are you really using Python 3.0 (which is marked in the versions)? If so, switch to 3.1 and see what you get.
msg93196 - (view) Author: Mark Dickinson (mark.dickinson) * (Python committer) Date: 2009-09-28 09:12
This is expected (and correct) behaviour for Python 2.x and 3.0. Note that the first example calls .1.__str__, while the second calls .1.__repr__. Python 2.6.2 (r262:71600, Aug 26 2009, 09:40:44) [GCC 4.2.1 (SUSE Linux)] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> str(.1) '0.1' >>> repr(.1) '0.10000000000000001' >>> str((.1,)) '(0.10000000000000001,)' >>> tuple(str(x) for x in (.1,)) ('0.1',)
msg93197 - (view) Author: Mark Dickinson (mark.dickinson) * (Python committer) Date: 2009-09-28 09:19
And as Eric says, you shouldn't see this behaviour in Python 3.1, since there str(0.1) == repr(0.1) == '0.1'. If you are seeing it in 3.1, then something interesting's happening: please reopen in that case. :)
msg93202 - (view) Author: Per Rosengren (scientist47) Date: 2009-09-28 10:31
I tried Python 3.1, and it does indeed not have this issue. Thanks for swift response!
msg93222 - (view) Author: Raymond Hettinger (rhettinger) * (Python committer) Date: 2009-09-28 18:14
You're seeing the difference between str(.1) and repr(.1). When printing the tuple, you're getting the str of the tuple but just the repr of its contents ('%.17g'). When printing the number directly, you're just getting the str of the number which is rounded to fewer decimal places for display ('%.12g'). This is easily seen with a number like pi: >>> from math import * >>> print(pi) 3.14159265359 >>> print((pi,)) (3.141592653589793,) >>> repr(pi) '3.141592653589793' >>> str(pi) '3.14159265359' In Py3.1, the repr computation was changed to show the shortest string the where float(x)==x. In the case of .1, the repr and str value happen to be the same (that is why Eric sees no difference in 3.1).
History
Date User Action Args
2022-04-11 14:56:53 admin set github: 51259
2009-09-28 18:14:07 rhettinger set nosy: + rhettingermessages: +
2009-09-28 10:31:23 scientist47 set messages: +
2009-09-28 09:19:38 mark.dickinson set messages: +
2009-09-28 09:14:34 mark.dickinson set status: open -> closedresolution: not a bug
2009-09-28 09:12:38 mark.dickinson set status: pending -> openmessages: +
2009-09-28 08:55:19 eric.smith set status: open -> pendingnosy: + mark.dickinson, eric.smithmessages: +
2009-09-28 07:43:56 scientist47 create