You have probably seen this in Python:
0.1 + 0.2 == 0.3 returns False. That looks like a bug, but it is not one.Why floats are approximate
A float stores a number in binary, the way your computer does. In binary,
0.1 cannot be written exactly any more than you can write 1/3 as a decimal without repeating digits (0.333...). A float keeps 53 binary digits, about 16 decimal digits, so it saves a value very close to 0.1 but not equal to it.print(repr(0.1))
print(repr(0.2))
print(repr(0.1 + 0.2))import math
print(0.1 + 0.2 == 0.3) # False
print(math.isclose(0.1 + 0.2, 0.3)) # Trueround() has its own quirks
print(round(2.5)) # 2, not 3
print(round(3.5)) # 4round() rounds halves to the nearest even number, a rule called banker's rounding. That is why round(2.5) gives 2 and round(3.5) gives 4.decimal.Decimal: exact base-10 numbers
from decimal import Decimal
print(Decimal('0.1') + Decimal('2'))
# 2.1 exactly, no binary noisedecimal.Decimal keeps the base-10 digits you type, so it is ideal for money and anything that must be exact in base 10.from decimal import Decimal
price = Decimal('2.675')
print(price.quantize(Decimal('0.01'))) # 2.68, exactly as written
print(round(2.675, 2)) # 2.67, the float surprise.quantize(Decimal('0.01')) rounds to two decimal places. Because the Decimal holds exactly 2.675, a true half, it rounds to 2.68; the float was a little under the half, so it could not. Like round(), quantize sends an exact half to the even digit, so Decimal('2.665') gives 2.66.fractions.Fraction: exact ratios
from fractions import Fraction
x = Fraction(1, 3)
print(x * 3) # 1 exactly
print(Fraction(2.5))Fraction stores a numerator and denominator as integers, so ratios like 1/3 never lose precision.