Python 3小数舍入到ROUND_HALF_UP上下文的一半 [英] Python 3 Decimal rounding half down with ROUND_HALF_UP context
问题描述
任何人都可以解释或提出一个修复程序,为什么当我在Python 3中将小数点后舍入到小数点后,将其舍入为2.5到2,而在Python 2中将其正确舍入为3:
Can anybody explain or propose a fix for why when I round a decimal in Python 3 with the context set to round half up, it rounds 2.5 to 2, whereas in Python 2 it rounds correctly to 3:
Python 3.4.3和3.5.2:
Python 3.4.3 and 3.5.2:
>>> import decimal
>>> context = decimal.getcontext()
>>> context.rounding = decimal.ROUND_HALF_UP
>>> round(decimal.Decimal('2.5'))
2
>>> decimal.Decimal('2.5').__round__()
2
>>> decimal.Decimal('2.5').quantize(decimal.Decimal('1'), rounding=decimal.ROUND_HALF_UP)
Decimal('3')
Python 2.7.6:
Python 2.7.6:
>>> import decimal
>>> context = decimal.getcontext()
>>> context.rounding = decimal.ROUND_HALF_UP
>>> round(decimal.Decimal('2.5'))
3.0
>>> decimal.Decimal('2.5').quantize(decimal.Decimal('1'), rounding=decimal.ROUND_HALF_UP)
Decimal('3')
推荐答案
注意,当您调用 round
时,会获得浮点值因此,不是十进制
。 舍入
将值强制为浮点数,然后根据舍入浮点数的规则将其舍入。
Notice that when you call round
you are getting a float value as a result, not a Decimal
. round
is coercing the value to a float and then rounding that according to the rules for rounding a float.
如果您在调用 round()
时使用可选的 ndigits
参数,您将获得一个十进制结果,在这种情况下,它将返回
If you use the optional ndigits
parameter when you call round()
you will get back a Decimal result and in this case it will round the way you expected.
Python 3.4.1 (default, Sep 24 2015, 20:41:10)
[GCC 4.9.2 20150212 (Red Hat 4.9.2-6)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import decimal
>>> context = decimal.getcontext()
>>> context.rounding = decimal.ROUND_HALF_UP
>>> round(decimal.Decimal('2.5'), 0)
Decimal('3')
我还没有找到 round(someDecimal)
返回int的文档,但是没有找到 round(someDecimal,ndigits)
返回一个十进制,但这似乎是在Python 3.3及更高版本中发生的情况。在Python 2.7中,调用 round()
时总是会返回浮点数,但是Python 3.3改进了 Decimal
与
I haven't found where it is documented that round(someDecimal)
returns an int but round(someDecimal, ndigits)
returns a decimal, but that seems to be what happens in Python 3.3 and later. In Python 2.7 you always get a float back when you call round()
but Python 3.3 improved the integration of Decimal
with the Python builtins.
如注释中所述, round()
代表 Decimal .__ round __()
并且确实显示了相同的行为:
As noted in a comment, round()
delegates to Decimal.__round__()
and that indeed shows the same behaviour:
>>> Decimal('2.5').__round__()
2
>>> Decimal('2.5').__round__(0)
Decimal('3')
我注意到 Fraction
的文档说:
__round__()
__round__(ndigits)
The first version returns the nearest int to self, rounding half to even.
The second version rounds self to the nearest multiple of Fraction(1, 10**ndigits)
(logically, if ndigits is negative), again rounding half toward even.
This method can also be accessed through the round() function.
因此,行为是一致的,因为没有参数它会更改结果的类型并将其四舍五入即使,但是似乎十进制
无法记录其 __ round __
方法的行为。
Thus the behaviour is consistent in that with no argument it changes the type of the result and rounds half to even, however it seems that Decimal
fails to document the behaviour of its __round__
method.
编辑以做注释,如Barry Hurley在评论中所述, round()
被记录为返回 int
(如果不带可选参数,则调用),如果给定了可选参数,则为浮点值。 https://docs.python.org/3/library/functions.html#round
Edit to note as Barry Hurley says in the comments, round()
is documented as returning a int
if called without the optional arguments and a "floating point value" if given the optional argument. https://docs.python.org/3/library/functions.html#round
这篇关于Python 3小数舍入到ROUND_HALF_UP上下文的一半的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!