如何在Python 3中使用传统四舍五入法对小数进行舍入?

3
我正在尝试使用Python版本3(特别是版本3.4.0)按照小学和中学教授的传统方法来四舍五入小数。
例如,对于小数0.745,我想将其四舍五入到最近的百分位。传统上,四舍五入的值应为0.75,但以下代码给出了0.74:
>>> import decimal
>>> a = decimal.Decimal("0.745")
>>> round(a, 2)
Decimal('0.74')

然而,将原始值更改为0.746似乎返回0.75:
>>> import decimal
>>> b = decimal.Decimal("0.746")
>>> round(b, 2)
Decimal('0.75')

这似乎与传统的四舍五入方式相矛盾(如果我没记错的话)。 有人能带我走向在Python中正确的四舍五入方法吗?

更新: 使用所选答案的指导,这是我的问题的完整代码解决方案:

>>> import decimal
>>> decimal.getcontext().rounding = decimal.ROUND_HALF_UP
>>> a = decimal.Decimal("0.745")
>>> round(a, 2)
Decimal('0.75')

1
你所观察到的并没有什么“意外”的。 - devnull
1
我相信作者所指的是在此处描述的四舍五入启发式方法。 - huu
呼,谢谢,那个链接正是我所指的。 - Omega Goggles
2个回答

6

这是预期的(也是最佳的)行为:所谓的“银行家舍入”,它是无偏的,并将半数四舍五入到最接近的偶数。

您始终可以:

import decimal
decimal.getcontext().rounding = decimal.ROUND_HALF_UP

请注意,ROUND_HALF_UP 有偏差,这就是为什么它不是默认值的原因。

谢谢Dietrich!直到现在我才第一次听说“银行家舍入法”。 经过进一步的研究,我同意它通常比我学过的传统舍入方法更好。 - Omega Goggles

2

如果您知道要舍入的精度,您可以额外添加一些来按照您想要的方式进行舍入(不一定是其他人期望的方式):

def round_my_way(dec, precision):
    dec += decimal.Decimal(1.0/10**(precision+1) / 2)
    return round(dec, precision)

print round_my_way(decimal.Decimal("0.746"), 2) # Prints 0.75
print round_my_way(decimal.Decimal("0.745"), 2) # Prints 0.75
print round_my_way(decimal.Decimal("0.744"), 2) # Prints 0.74

谢谢你,Huu!虽然另一个答案更相关于这个问题,但这仍然是很好知道的。再次感谢! - Omega Goggles
没问题!我投赞成票给另一个答案,因为我不知道你可以像那样改变舍入启发式。 - huu

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接