Search code examples
pythonpython-2.7python-3.6six

Not able get exact str(float) result of python 2 in python 3


I'm trying to port some py2 code to py3, and I'd like to somehow reproduce the exact string representation of a floating number that py2 would have returned, but in python 3.

e.g.

from __future__ import print_function

a = 1.5 * 0.4
string = str(a)
print(string)

In python3, the output is 0.6000000000000001 , vs python2, where the output is 0.6, and I understand why:

Why does str(float) return more digits in Python 3 than Python 2?

However, is there a way where I can faithfully reproduce (in python3) what str(a) would have been (e.g. same behavior in py2 and py3), for arbitrary values of a?

I tried this

import six
a = 1.5 * 0.4
string = str(a)
if six.PY3:
    string = '{:.12g}'.format(a)
print(string)

The above "almost" works, but in the case a = 5 , we'll get different output (5.0 for py2 and 5 for py3)


Solution

  • The problem comes from the fact that as the same way some fractions are note easily represented in decimal form (for example 1/3 = 0.33333333…), some fractions are not easily represented in binary form (for example 1/3 = 0.01010101…). But if you want to have as consistent results as a decimal numbers, consider looking at the decimal module (which is available in Python 2.7 and 3). You could have something like this:

    from decimal import Decimal
    
    a = Decimal('1.5') * Decimal('0.4')
    result = str(a)
    print(result)