Python round(1 / 2)的默认值为0。如何将浮点数0.5四舍五入到1.0,同时仍将0.45四舍五入到0.0,就像通常的学校四舍五入一样?
round(1 / 2)
blmhpbnm1#
实际上,目前认为 * 不 * 盲目地将 *.5向上舍入是正确的。相反,将 *.5舍入到最接近的偶数是正确的。Python 3实现了这种“适当”的“银行家舍入”形式,但许多其他语言没有(然而)。盲目地四舍五入 *.5会产生轻微的偏差,但“银行家四舍五入”有助于平衡它。请参阅this thread了解更多信息。所以...
方法一
您可以有条件地使用ceil(...)函数(来自math module)。您必须有条件地执行此操作,以便对小于0.5的值也保持常规的舍入行为。请尝试以下操作(注意,这不是非常健壮的,因为它只适用于正值...它应该能够很容易地适应正值和负值):
ceil(...)
import math val = 1.5 x = 0 if (float(val) % 1) >= 0.5: x = math.ceil(val) else: x = round(val)
注意ceil(...)函数将返回一个整数,而不是一个浮点数。这应该不是一个大问题,但现在你知道了。
方法二
从我上面链接的帖子来看,似乎还有一个选择是使用decimal模块来模拟“旧”的舍入方式。我有点复制和粘贴,但在这里你可以:
import decimal x = decimal.Decimal('1.5').quantize(decimal.Decimal('1'), rounding=decimal.ROUND_HALF_UP)
假设舍入的decimal.ROUND_HALF_UP形式是你要找的。这样你就不必有条件地使用ceil(...)函数。
decimal.ROUND_HALF_UP
qij5mzcb2#
得到“学校”舍入,从0开始舍入中间的值,也可以用于负数,可以使用下面的函数。这也是Python 2中的舍入。
def round_school(x): i, f = divmod(x, 1) return int(i + ((f >= 0.5) if (x > 0) else (f > 0.5)))
一些示例结果:
1.50: 2 1.49: 1 0.50: 1 0.49: 0 -0.49: 0 -0.50: -1 -1.49: -1 -1.50: -2
avwztpqn3#
decimal
from decimal import Decimal, ROUND_HALF_UP def round(number, ndigits=None): """Always round off""" exp = Decimal('1.{}'.format(ndigits * '0')) if ndigits else Decimal('1') return type(number)(Decimal(number).quantize(exp, ROUND_HALF_UP)) print(round(4.115, 2), type(round(4.115, 2))) print(round(4.116, 2), type(round(4.116, 2))) print(round(4.125, 2), type(round(4.125, 2))) print(round(4.126, 2), type(round(4.126, 2))) print(round(2.5), type(round(2.5))) print(round(3.5), type(round(3.5))) print(round(5), type(round(5))) print(round(6), type(round(6))) # 4.12 <class 'float'> # 4.12 <class 'float'> # 4.13 <class 'float'> # 4.13 <class 'float'> # 3.0 <class 'float'> # 4.0 <class 'float'> # 5 <class 'int'> # 6 <class 'int'>
math
import math def round(number, ndigits=0): """Always round off""" exp = number * 10 ** ndigits if abs(exp) - abs(math.floor(exp)) < 0.5: return type(number)(math.floor(exp) / 10 ** ndigits) return type(number)(math.ceil(exp) / 10 ** ndigits) print(round(4.115, 2), type(round(4.115, 2))) print(round(4.116, 2), type(round(4.116, 2))) print(round(4.125, 2), type(round(4.125, 2))) print(round(4.126, 2), type(round(4.126, 2))) print(round(2.5), type(round(2.5))) print(round(3.5), type(round(3.5))) print(round(5), type(round(5))) print(round(6), type(round(6))) # 4.12 <class 'float'> # 4.12 <class 'float'> # 4.13 <class 'float'> # 4.13 <class 'float'> # 3.0 <class 'float'> # 4.0 <class 'float'> # 5 <class 'int'> # 6 <class 'int'>
import math from timeit import timeit from decimal import Decimal, ROUND_HALF_UP def round1(number, ndigits=None): exp = Decimal('1.{}'.format(ndigits * '0')) if ndigits else Decimal('1') return type(number)(Decimal(number).quantize(exp, ROUND_HALF_UP)) def round2(number, ndigits=0): exp = number * 10 ** ndigits if abs(exp) - abs(math.floor(exp)) < 0.5: return type(number)(math.floor(exp) / 10 ** ndigits) return type(number)(math.ceil(exp) / 10 ** ndigits) print(timeit('round1(123456789.1223456789, 5)', globals=globals())) print(timeit('round2(123456789.1223456789, 5)', globals=globals())) # 1.9912803000000001 # 1.2140076999999998
math的速度更快。
3条答案
按热度按时间blmhpbnm1#
实际上,目前认为 * 不 * 盲目地将 *.5向上舍入是正确的。相反,将 *.5舍入到最接近的偶数是正确的。Python 3实现了这种“适当”的“银行家舍入”形式,但许多其他语言没有(然而)。盲目地四舍五入 *.5会产生轻微的偏差,但“银行家四舍五入”有助于平衡它。请参阅this thread了解更多信息。所以...
方法一
您可以有条件地使用
ceil(...)
函数(来自math module)。您必须有条件地执行此操作,以便对小于0.5的值也保持常规的舍入行为。请尝试以下操作(注意,这不是非常健壮的,因为它只适用于正值...它应该能够很容易地适应正值和负值):注意
ceil(...)
函数将返回一个整数,而不是一个浮点数。这应该不是一个大问题,但现在你知道了。方法二
从我上面链接的帖子来看,似乎还有一个选择是使用decimal模块来模拟“旧”的舍入方式。我有点复制和粘贴,但在这里你可以:
假设舍入的
decimal.ROUND_HALF_UP
形式是你要找的。这样你就不必有条件地使用ceil(...)
函数。qij5mzcb2#
得到“学校”舍入,从0开始舍入中间的值,也可以用于负数,可以使用下面的函数。这也是Python 2中的舍入。
一些示例结果:
avwztpqn3#
总是四舍五入
decimal
math
对比
math
的速度更快。