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 <rep...@bugs.python.org>
<http://bugs.python.org/issue24827>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com

Reply via email to