Python uses the CPU's native float which is a binary estimate of the true floating point number. Its not a problem with python per se, its the inherent imprecision in fixed length binary floats. Simply writing your wanted value as a float demonstrates the problem:
>>> f"{499000500499500000.:f}"
'499000500499500032.000000
If you need more precision than float
offers, the decimal
module may work for you.
>>> from decimal import Decimal
>>> a = Decimal(1000000000)
>>> b = Decimal(1000000)
>>> max_d = (a - b + 1) * (a - b) / 2
>>> max_d
Decimal('499000500499500000')
>>> max_ = int(max_d)
>>> max_
499000500499500000
float
exists, even though it is an estimate of a true real number, because this lack of precision can usually be factored into the algorithm. When this error is too much, or when you are doing something like accounting where the error is significant, there is the alternative decimal
.
See Floating Point Arithmetic: Issues and Limitations
Another option is to use floor division which doesn't go through float
.
>>> a = 1000000000
>>> b = 1000000
>>> (a - b + 1) * (a - b) // 2
499000500499500000
That looks better! But, there is still a lack of precision depending on what you are dividing.