astanin / python-tabulate

Pretty-print tabular data in Python, a library and a command-line utility. Repository migrated from bitbucket.org/astanin/python-tabulate.
https://pypi.org/project/tabulate/
MIT License
2.08k stars 162 forks source link

Inconsistent 'floatfmt'? #330

Closed cwrpp closed 2 months ago

cwrpp commented 2 months ago

When using floatfmt i get inconsistent results. The digit 5 is sometimes rounded up, sometimes down.

For example:

print(tabulate([["right", 3.14],["wrong", 3.15], ["right", 3.75], ["wrong", 3.65]], floatfmt=".1f"))

gives:

-----  ---
right  3.1
wrong  3.1
right  3.8
wrong  3.6
-----  ---

I am using tabulate 0.9.0 and python 3.12.4! Thanks!

eliegoudout commented 2 months ago

It's not a bug, rather a subtle implementation artifact that is well-documented. From python built-in round doc:

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.

Also, note that rounding occurs towards the even integer for floats of the form *.5:

If two multiples are equally close, rounding is done toward the even choice (so, for example, both round(0.5) and round(-0.5) are 0, and round(1.5) is 2)

This is called banker's rounding.

cwrpp commented 2 months ago

Oh, that was my mistake! Thanks for the quick response. By the way, I really enjoy using tabulate!