Floating point behavior in Python 2.6 vs 2.7

2019-02-25 00:49发布

问题:

So I break out the Python 2.6 interpreter and I get this:

Python 2.6.6 (r266:84292, Nov 22 2013, 12:16:22) 
[GCC 4.4.7 20120313 (Red Hat 4.4.7-4)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> 2.1
2.1000000000000001
>>> 2.2
2.2000000000000002
>>> 2.2
2.2000000000000002

However in Python 2.7 I get more human-like results like below:

Python 2.7.5+ (default, Sep 19 2013, 13:48:49) 
[GCC 4.8.1] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> 5.4
5.4
>>> 1.1
1.1
>>> 0.2
0.2
>>> 

I 'd like to ask why is this happening and how could I possibly make Python 2.6 behave like 2.7?

回答1:

The float.__repr__() and float.__str__() methods in Python 2.7 changed; the Python 3.1 float-to-string conversion method was backported and values are now rounded.

The C source code for float.__str__() formats a floating point value using the g formatter code to the sprintf() function, with a precision of 12 positions.

To get the same result in Python 2.6, you'll have to format the string yourself:

'%.12g' % fp_value

or use the format() function:

format(fp_value, '.12g')

Note that in Python 2.7 only the representation changed, not the actual values. Floating point values are still binary approximations of real numbers, and binary fractions don't always add up to the exact number represented.

If you need to have more precision than what float approximations offer you, you need to switch to using the decimal.Decimal() type instead. This maintains precision, at the cost of speed (floating point arithmetic is handled in hardware on modern computers).