Python's floats are internally represented in base 2 over a limited number bits (e.g. 64). This means that some rational values cannot be stored exactly. In the same way that 2/3 needs an infinite number of decimal places in base 10 and ends up being rounded to 0.6666....6667 , there are fractions in base 2 (different ones) that need a similar type of rounding.
You can use the decimal module's Decimal class to manipulate numbers in a more familiar base-10 representation.
from decimal import Decimal
x = Decimal("0.1")
y = x+x+x
print(y == Decimal("0.3")) # True
print(y) # 0.3
Note that i'm initializing the numbers from a string because Decimal(0.3)
would make an imprecise decimal value from the already approximated 0.3 float value.
In the end, this just moves the problem to different values as you can see here:
x = Decimal(1)/Decimal(3)
y = x+x+x
print(y) # 0.9999999999999999999999999999
To completely avoid this precision issue with rational numbers, you would have to use the fractions module. But then you won't be able to perform some operations and will still be limited for irrational values (and transcendentals such as π and e).
x = Fraction(1,3) # 1/3
y = x+x+x
print(y) # 1
x = Fraction(1,10) # 0.1
y = x+x+x
print(y) # 3/10
print(float(y)) # 0.3