Take a look at the documentation:
Note The behavior of round()
for floats can be surprising: for example, round(2.675, 2)
gives 2.67
instead of the expected
2.68
. This is not a bug: it’s a result of the fact that most decimal
fractions can’t be represented exactly as a float. See Floating
Point Arithmetic: Issues and Limitations for more information.
If you keep digging (i.e. click that link), you'll find an example similar to yours:
The documentation for the built-in round()
function says that it
rounds to the nearest value, rounding ties away from zero. Since the
decimal fraction 2.675
is exactly halfway between 2.67
and 2.68
,
you might expect the result here to be (a binary approximation to)
2.68
. It’s not, because when the decimal string 2.675
is converted
to a binary floating-point number, it’s again replaced with a binary
approximation, whose exact value is
2.67499999999999982236431605997495353221893310546875
String formatting won't fix your problem either. The floating point number just isn't stored the way you'd expect it to be:
>>> '{:0.2f}'.format(1.555)
'1.55'
This isn't really a "fix", but Python does have a decimal
module, which is designed for floating point arithmetic:
>>> from decimal import Decimal
>>> n = Decimal('1.555')
>>> round(n, 2)
Decimal('1.56')