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