如何在Python 3.x中从0舍入?

zd287kbt  于 2023-11-20  发布在  Python
关注(0)|答案(9)|浏览(162)

在Python 2中,舍入是从0开始的,所以,例如,round(0.5)1.0
然而,在Python 3.x中,四舍五入是朝着偶数选择进行的,所以round(0.5)0
我可以在Python 3.x中使用什么函数来获得旧的行为?

m1m5dgzv

m1m5dgzv1#

如果你的代码对性能不是特别敏感,你可以使用标准的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

字符串

smtd7mpg

smtd7mpg2#

四舍五入为整数时相当于Python 2.7 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,则对于大向量的性能要高得多(但对于标量来说非常慢):

import numpy as np
def py2round(x):
    return np.copysign(np.floor(abs(x) + 0.5), x).astype(int)

dm7nw8vv

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

svmlkihl

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

字符串

3okqufwl

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.你可以改变这返回值为

return math.ceil(aX)*(aX/x) if x is not 0 else 0

g9icjywg

g9icjywg6#

与其他解决方案非常相似,但使用了简写的 if 语句而不是函数:

segments = ceil(gamma / 90) if gamma > 0 else floor(gamma/90)

字符串

k2arahey

k2arahey7#

我用这个:

f = lambda i:i-i%(1|-(i>0))

print(f('your float number'))

字符串
希望有用!

2mbi3lxu

2mbi3lxu8#

对于正数,下面的方法对我有效:

>>> import math
>>> x = 0.5
>>> (math.trunc(x*2)+1) >> 1
1

字符串

lb3vh1jj

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

相关问题