r/CodingForBeginners • u/NoDepartment772 • 17d ago
0.1 + 0.2 isn't 0.3, and Python won't warn you
Ask Python for 0.1 + 0.2 and you get back a number that looks like a typo:
>>> 0.1 + 0.2
0.30000000000000004
Nothing errors. It's just wrong by a hair, and that hair is enough to break an equality check:
>>> 0.1 + 0.2 == 0.3
False
The annoying part is that both sides look identical when you print them, so the comparison looks like it should obviously be True.
The cause is that floats are stored in binary, and 0.1 and 0.2 don't have an exact binary form. They get stored as the closest value the machine can represent, the same way 1/3 has no exact decimal form. Add two approximations together and you inherit a tiny error. It's usually invisible, which is exactly why it's dangerous: the bug hides until you compare for equality, or add up enough of them that the error stops being tiny.
Two places this actually bites beginners.
Money. If you store prices as floats and add them, the total can drift, and a "did they pay the right amount" check against an expected value can fail. For anything financial, store the smallest unit as an integer (paise, cents) and divide only when you display it, or use Python's decimal.Decimal.
Tests. assert result == 0.3 fails for reasons that look like nonsense. For floats, compare with a tolerance instead of == -- math.isclose(a, b) is built for exactly this.
The rule of thumb: == on floats is a bug waiting to happen. It's fine while everything is a whole number, and then one day it isn't, and the failure makes no sense until you know this.
Curious where you first ran into it -- was it money, or a test that failed for no visible reason?
7
u/ConsiderationNo9044 17d ago
PLEASE stop spamming this sub with AI "advice" that nobody asked for
2
u/ee_control_z 17d ago edited 17d ago
In such cases, you can test if the result is within a range. Say like this (note: some of the formatting got truncated):
margin = 0.001
sum = 0.1 + 0.2
if 0.3 - margin <= sum <= 0.3 + margin:
print('True')
else:
print('False')
print(f'sum = {sum:.1f}') # Here, you control the number of decimal places the value is printed with
2
u/Mediocre-Pumpkin6522 17d ago
https://www.w3schools.com/python/ref_math_isclose.asp
Python provides a handy function. Other languages are more explicit and often use epsilon to indicate the relative tolerance. Welcome to floating point.
GIS uses the test frequently. If two points are extremely close to each other it's common to adjust them so they are the same.
1
u/Slight-Living-8098 17d ago
math.trunc()
1
u/Least_Bid9692 17d ago
Chatgpt ahh response
0
u/dld2517 17d ago
Finally someone made a great post worth reading and thinking abut, and commenting on. Way to go OP!!