Python 3小数舍入到ROUND_HALF_UP上下文的一半 [英] Python 3 Decimal rounding half down with ROUND_HALF_UP context

查看:501
本文介绍了Python 3小数舍入到ROUND_HALF_UP上下文的一半的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

任何人都可以解释或提出一个修复程序,为什么当我在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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆