Showing posts with label python. Show all posts
Showing posts with label python. Show all posts

Saturday, December 10, 2022

calculate accurately in Python3

How float point numbers are represented and stored is defined in IEEE-754. If you use float in Python, Double in Java, REAL in MySQL or PostgreSQL, the numbers you read may not be exact the ones you saved previously. The inaccuracy becomes even more unpredictable if we take rounding into consideration.

Here're few examples in Python to give you a better understanding.

f1 = 0.215
f2 = 0.235
f = f1 + f2
g = 0.1
print(f, g, f * g, round(f * g, 2))

f1 = 0.216
f2 = 0.234
f = f1 + f2
g = 0.1
print(f, g, f * g, round(f * g, 2))

from decimal import Decimal
f1 = Decimal(0.215)
f2 = Decimal(0.235)
f = f1 + f2
g = Decimal(0.1)
print(f, g, f * g, round(f * g, 2))

f1 = Decimal("0.215")
f2 = Decimal("0.235")
f = f1 + f2
g = Decimal("0.1")
print(f, g, f * g, round(f * g, 2))

from decimal import getcontext, ROUND_HALF_UP
getcontext().rounding = ROUND_HALF_UP
f1 = Decimal("0.215")
f2 = Decimal("0.235")
f = f1 + f2
g = Decimal("0.1")
print(f, g, f * g, round(f * g, 2))

0.44999999999999996 0.1 0.045 0.04
0.45 0.1 0.045000000000000005 0.05
0.4499999999999999833466546306 0.1000000000000000055511151231257827021181583404541015625 0.04500000000000000083266726847 0.05
0.450 0.1 0.0450 0.04
0.450 0.1 0.0450 0.05

Saturday, January 16, 2010

Floating point arithmetic in Python 3 is much more accurate

There is always limited precision in floating point arithmetic due to conversion between decimal and binary. But I found Python 3 becomes much more accurate.

 zhao@nettop:~$ python  
 Python 2.6.4 (r264:75706, Dec 7 2009, 18:45:15)   
 [GCC 4.4.1] on linux2  
 Type "help", "copyright", "credits" or "license" for more information.  
 >>> 12.6 / 2  
 6.2999999999999998  
 >>> 12.6 + 0.01
 12.609999999999999
 >>> float('3.2')
 3.2000000000000002  

 zhao@nettop:~$ python3  
 Python 3.1.1+ (r311:74480, Nov 2 2009, 14:49:22)   
 [GCC 4.4.1] on linux2  
 Type "help", "copyright", "credits" or "license" for more information.  
 >>> 12.6 / 2  
 6.3  
 >>> 12.6 + 0.01  
 12.61  
 >>> float('3.2')  
 3.2  
Who has any idea about this?

Update on 27/12/2020, Python 2.7 fixed it as well.
 $ python
 Python 2.7.18rc1 (default, Apr  7 2020, 12:05:55) 
 [GCC 9.3.0] on linux2
 Type "help", "copyright", "credits" or "license" for more information.
 >>> 12.6 / 2
 6.3
 >>> 12.6 + 0.01
 12.61
 >>> float('3.2')
 3.2