是否有一个内置函数可以像下面这样舍入?

10 -> 10
12 -> 10
13 -> 15
14 -> 15
16 -> 15
18 -> 20

当前回答

一个只适用于整型的解决方案(它接受浮点数,但舍入行为就像小数组件不存在一样),但不像任何依赖于临时转换到浮点数的解决方案(所有math.floor/math.浮点数)。基于天花板的解决方案,所有的解决方案使用/,大多数解决方案使用round),它适用于任意巨大的int输入,永远不会失去精度,永远不会引发异常或导致无穷大的值。

它是一个最简单的解决方案的改编,四舍五入到一个数字的下一个低倍数:

def round_to_nearest(num, base=5):
    num += base // 2
    return num - (num % base)

它所基于的四舍五入食谱是:

def round_down(num, base=5):
    return num - (num % base)

唯一的变化是你提前给数字加上一半的基数,所以它四舍五入到最接近的值。对于精确的中点值,只有偶数底数才可能,因此round_to_nearest(3,6)将舍入为6而不是0,而round_to_nearest(- 3,6)将舍入为0而不是-6。如果希望中点值向下舍入,可以将第一行更改为num += (base - 1) // 2。

其他回答

的值加上0.5,可以“欺骗”int()使其舍入而不是舍入 传递给int()的数字。

那么这个呢:

 def divround(value, step):
     return divmod(value, step)[0] * step

我不知道Python中的标准函数,但这对我来说是可行的:

Python 3

def myround(x, base=5):
    return base * round(x/base)

很容易理解为什么上面的方法是有效的。你要确保你的数字除以5是一个整数,四舍五入正确。所以,我们首先做的就是(round(x/5))然后因为我们除以5,所以我们也乘以5。

我通过给它一个基本参数使函数更通用,默认值为5。

Python 2

在Python 2中,需要使用float(x)来确保/执行浮点除法,并且需要最终转换为int,因为在Python 2中round()返回的是浮点值。

def myround(x, base=5):
    return int(base * round(float(x)/base))

divround的修改版本:-)

def divround(value, step, barrage):
    result, rest = divmod(value, step)
    return result*step if rest < barrage else (result+1)*step

如果有人需要“财务四舍五入”(0.5位总是向上):

def myround(x, base=5):
    roundcontext = decimal.Context(rounding=decimal.ROUND_HALF_UP)
    decimal.setcontext(roundcontext)
    return int(base *float(decimal.Decimal(x/base).quantize(decimal.Decimal('0'))))

根据文档,其他舍入选项是:

ROUND_CEILING(朝向无限) ROUND_DOWN(趋近于零) ROUND_FLOOR(朝向-∞) ROUND_HALF_DOWN(当平局趋于0时最接近) ROUND_HALF_EVEN(最接近偶数) ROUND_HALF_UP(到最接近的平局从0开始) ROUND_UP(远离零) ROUND_05UP(如果四舍五入后的最后一位为0或5,则远离0;否则趋于零)

默认情况下,Python使用ROUND_HALF_EVEN,因为它有一些统计优势(四舍五入的结果没有偏见)。