在Python 2中,舍入是从0开始的,所以,例如,round(0.5)是1.0。然而,在Python 3.x中,四舍五入是朝着偶数选择进行的,所以round(0.5)是0。我可以在Python 3.x中使用什么函数来获得旧的行为?
0
round(0.5)
1.0
m1m5dgzv1#
如果你的代码对性能不是特别敏感,你可以使用标准的decimal库来实现你想要的结果。Decimal().quantize()允许选择舍入方法:
decimal
Decimal().quantize()
from decimal import Decimal, ROUND_HALF_UP result = float(Decimal(0.5).quantize(Decimal(0), rounding=ROUND_HALF_UP)) print(result) # Will output 1.0
字符串
smtd7mpg2#
四舍五入为整数时相当于Python 2.7 round()(单参数):
round()
import math def py2round(x): if x >= 0.0: return math.floor(x + 0.5) else: return math.ceil(x - 0.5)
字符串另一个更简洁但对于标量值更昂贵的选项:
def py2round(x): return int(math.copysign(math.floor(abs(x) + 0.5), x))
型然而,如果将math替换为numpy,则对于大向量的性能要高得多(但对于标量来说非常慢):
math
numpy
import numpy as np def py2round(x): return np.copysign(np.floor(abs(x) + 0.5), x).astype(int)
型
dm7nw8vv3#
要在Python 3中获得round()的单参数形式的Python 2舍入行为,您可以使用如下自定义函数:
def myround(n): if round(n + 1) - round(n) == 1: return float(round(n)) return n + abs(n) / n * 0.5
字符串演示:
>>> myround(0.5) 1.0 >>> myround(1.5) 2.0 >>> myround(-0.5) -1.0 >>> myround(-1.5) -2.0 >>> myround(1) 1.0
svmlkihl4#
根据CPython源代码,基本思想非常简单:使用_Py_dg_dtoa将双精度数转换并舍入为十进制字符串,然后使用_Py_dg_strtod将十进制字符串转换回双精度数。有一个小困难:Python 2.x期望round从零开始舍入一半,而_Py_dg_dtoa则舍入一半到偶数。所以我们需要一些方法来检测和纠正中途情况。如果你关心性能,可以考虑复制相关的C代码并作为扩展导入。但是如果你不关心,这里有一个Python实现:
def myround(a): num = str(a) num = str.split('.', 1) if int(num[1][0]) >= 5: return int(num[0]) + 1 if a > 0 else int(num[0]) - 1 else: return int(num[0]) - 1 if a > 0 else int(num[0]) + 1
3okqufwl5#
def round_up(x): aX = abs(x) return math.ceil(aX)*(aX/x)
字符串这个解决方案可能对你有用。对于x = -1.2 round_up(x) = -2,x = 2.3 round_up(x) = 3等编辑:这个解决方案将崩溃为x = 0.你可以改变这返回值为
round_up(x) = -2
round_up(x) = 3
return math.ceil(aX)*(aX/x) if x is not 0 else 0
g9icjywg6#
与其他解决方案非常相似,但使用了简写的 if 语句而不是函数:
segments = ceil(gamma / 90) if gamma > 0 else floor(gamma/90)
k2arahey7#
我用这个:
f = lambda i:i-i%(1|-(i>0)) print(f('your float number'))
字符串希望有用!
2mbi3lxu8#
对于正数,下面的方法对我有效:
>>> import math >>> x = 0.5 >>> (math.trunc(x*2)+1) >> 1 1
lb3vh1jj9#
这是我提出的一个可能的解决方案:
import math def round_away_from_zero(x): a = abs(x) r = math.floor(a) + math.floor(2 * (a % 1)) return r if x >= 0 else -r
字符串测试:
round_away_from_zero(0.5) # 1 round_away_from_zero(1.5) # 2 round_away_from_zero(2.5) # 3 round_away_from_zero(-0.5) # -1 round_away_from_zero(-1.5) # -2 round_away_from_zero(-2.5) # -3
9条答案
按热度按时间m1m5dgzv1#
如果你的代码对性能不是特别敏感,你可以使用标准的
decimal
库来实现你想要的结果。Decimal().quantize()
允许选择舍入方法:字符串
smtd7mpg2#
四舍五入为整数时相当于Python 2.7
round()
(单参数):字符串
另一个更简洁但对于标量值更昂贵的选项:
型
然而,如果将
math
替换为numpy
,则对于大向量的性能要高得多(但对于标量来说非常慢):型
dm7nw8vv3#
要在Python 3中获得
round()
的单参数形式的Python 2舍入行为,您可以使用如下自定义函数:字符串
演示:
型
svmlkihl4#
根据CPython源代码,
基本思想非常简单:使用_Py_dg_dtoa将双精度数转换并舍入为十进制字符串,然后使用_Py_dg_strtod将十进制字符串转换回双精度数。有一个小困难:Python 2.x期望round从零开始舍入一半,而_Py_dg_dtoa则舍入一半到偶数。所以我们需要一些方法来检测和纠正中途情况。
如果你关心性能,可以考虑复制相关的C代码并作为扩展导入。但是如果你不关心,这里有一个Python实现:
字符串
3okqufwl5#
字符串
这个解决方案可能对你有用。
对于x = -1.2
round_up(x) = -2
,x = 2.3round_up(x) = 3
等编辑:这个解决方案将崩溃为x = 0.你可以改变这返回值为
型
g9icjywg6#
与其他解决方案非常相似,但使用了简写的 if 语句而不是函数:
字符串
k2arahey7#
我用这个:
字符串
希望有用!
2mbi3lxu8#
对于正数,下面的方法对我有效:
字符串
lb3vh1jj9#
这是我提出的一个可能的解决方案:
字符串
测试:
型