Format String Rounding Bug

91 Views Asked by At

Is it a bug or expected behavior to have rounding behave differently depending on the number of visible decimal places?

Demo via Interactive Interpreter

Python 3.8.10
>>> a = 1.555
>>> f'{a:.0f}'
'2'
>>> f'{a:.1f}'
'1.6'
>>> f'{a:.2f}'
'1.55'
>>> f'{a:.3f}'
'1.555'
2

There are 2 best solutions below

7
atline On BEST ANSWER

One way to make it accurate is to use Decimal:

But, you could see Decimal(1.555) will output next:

>>> Decimal(1.555)
Decimal('1.5549999999999999378275106209912337362766265869140625')

Above could explain why we get the 1.55, as the 3rd number is 4.

To fix that, we should change float to str as float is not accurate.

C:\Windows\System32>python
Python 3.9.9 (tags/v3.9.9:ccb0e6a, Nov 15 2021, 18:08:50) [MSC v.1929 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> from decimal import Decimal
>>> a = "1.555"
>>> float(Decimal(a).quantize(Decimal("0")))
2.0
>>> float(Decimal(a).quantize(Decimal("0.1")))
1.6
>>> float(Decimal(a).quantize(Decimal("0.01")))
1.56
>>> float(Decimal(a).quantize(Decimal("0.001")))
1.555
>>>

So, when you need accurate, consider to using Decimal.

1
user650654 On

a is actually slightly smaller than 1.555 due to imprecise representation of floating point values.

You can see this, for example, as follows:

f"{a:.40f}"
'1.5549999999999999378275106209912337362766'

Or,

f"{a:.64f}"
'1.5549999999999999378275106209912337362766265869140625000000000000'