Python 3使用ROUND_HALF_UP上下文舍入一半

Bar*_*ley 11 python decimal rounding python-3.x

任何人都可以解释或提出一个解决方法,为什么当我在Python 3中舍入小数,并将上下文设置为舍入一半时,它将舍入2.5到2,而在Python 2中它正确舍入为3:

Python 3.4.3和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')
Run Code Online (Sandbox Code Playgroud)

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')
Run Code Online (Sandbox Code Playgroud)

Dun*_*can 12

请注意,当您调用时,round您将获得浮点值,而不是a Decimal.round将值强制转换为float,然后根据舍入浮点数的规则舍入该值.

如果ndigits在调用时使用可选参数,round()则会返回十进制结果,在这种情况下,它将按预期方式舍入.

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')
Run Code Online (Sandbox Code Playgroud)

我还没有找到round(someDecimal)返回int但round(someDecimal, ndigits)返回小数的文档,但这似乎是Python 3.3及更高版本中发生的情况.在Python 2.7中,你总是在调用时得到一个浮点数,round()但是Python 3.3改进了Decimal与Python内置函数的集成.

正如评论中所指出的那样,round()代表们Decimal.__round__()确实表现出同样的行为:

>>> Decimal('2.5').__round__()
2
>>> Decimal('2.5').__round__(0)
Decimal('3')
Run Code Online (Sandbox Code Playgroud)

我注意到文档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.
Run Code Online (Sandbox Code Playgroud)

因此行为是一致的,因为没有参数它会改变结果的类型并将一半舍入到偶数,但似乎Decimal无法记录其__round__方法的行为.

编辑注意Barry Hurley在评论中说,round()记录为int在没有可选参数的情况下返回一个if,如果给出可选参数,则返回"浮点值".https://docs.python.org/3/library/functions.html#round