Zachary Ware added the comment:
I think the key point that you're missing (and which I could have made clearer
in my previous message) is that `Decimal(2.675) != Decimal('2.675')`. In the
first case, a Decimal instance is created from a float, and 2.675 cannot be
represented perfectly in base-2. The float is actually
2.67499999999999982236431605997495353221893310546875, but Python knows you're
human and almost certainly didn't want that number, so it shows you 2.675 when
asked. The second Decimal instance is created from the string '2.675', and is
converted straight to base-10.
Moving on to the rounding, both the float 2.675 and the Decimal created from
the float 2.675 round down to 2.67 (or nearly, in the case of the float),
because they're actually 2.674999..., and 4 rounds down. The Decimal created
from a string rounds to 2.68, because it actually is 2.675 and 5 rounds to even
(in this case, 8).
>>> from decimal import Decimal as D
>>> f = 2.675
>>> s = str(f)
>>> s # Python chooses the shortest representation
'2.675'
>>> df = D(f)
>>> ds = D(s)
>>> f, df, ds
(2.675, Decimal('2.67499999999999982236431605997495353221893310546875'),
Decimal('2.675'))
>>> f == df
True
>>> f == ds
False
>>> df == ds
False
>>> D(round(f, 2)), D(round(df, 2)), D(round(ds, 2))
(Decimal('2.6699999999999999289457264239899814128875732421875'),
Decimal('2.67'), Decimal('2.68'))
The moral of the story is: everything is working as expected and don't create
Decimals from floats unless you want the base-2 approximation of the value.
----------
title: round(1.65, 1) return 1.6 with decima modulel -> round(1.65, 1) return
1.6 with decimal
_______________________________________
Python tracker <[email protected]>
<http://bugs.python.org/issue24827>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe:
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com