使用Floor/Ceil将小数舍入为5的整数

2024-05-23 21:37:00 发布

您现在位置:Python中文网/ 问答频道 /正文

我一直在使用下面的代码轻松地四舍五入到1dp,我需要.5s向上四舍五入,例如,我想要一个值,比如36.25,四舍五入到36.3,而不是36.2

def my_round(n, ndigits=1):
    try:
       part = n * 10 ** ndigits
       delta = part - int(part)
       # always round "away from 0"
       if delta >= 0.5 or -0.5 < delta <= 0:
           part = math.ceil(part)
       else:
           part = math.floor(part)
       val =  part/(10 ** ndigits)
    except ValueError:
       val = np.nan
    return val

现在我需要将df中的不同十进制列四舍五入到最接近的5个整数。有人能建议我如何调整我的原始代码来做到这一点吗?例如,我需要一个值,比如702.5000,四舍五入到705。使用普通圆()显然是700。在本例中,所有其他正常舍入规则应适用,例如

702.222 to 700,
707.466 to 705,
703.021 to 705


Tags: to代码frommydefmathvalalways
3条回答

要四舍五入到某个小数位数,请使用以下命令:

def my_round(x: float, round_to: float = 5, dp: int = 0) -> float: 
    round_to *= 10**dp 
    x *= 10**dp 
    return ((x + round_to / 2) // round_to * round_to) / 10**dp 

测试它:

values = [702.500, 702.222, 707.466, 703.021]
targets = [705., 700., 705., 705.]
assert [my_round(x, 5, 0) for x in values] == targets
assert my_round(3.25, 0.1, 1) == 36.3

最快的方法是除以5,四舍五入,然后乘以5。这完全是数学上的事实,它会起作用

5*round(n/5)

而且不需要if语句来决定何时使用floorceil,因为round已经默认为这个逻辑

编辑:正如所指出的,这适用于除2.5结尾的值之外的所有值,当需要进行舍入时(在实践中,许多示例不需要这样做)

由于Ashwin的回答已经完成了这一点,我将给出一个修复,在一行中完成它,而不使用函数定义,尽管它并不漂亮:

5 * (int(x/5) + 1 - round(x/5 % 1))

或使用ceil稍微清洁:

5*(math.ceil(x/5) - round(x/5 % 1))

利用这个事实,round的行为就像我们从上面所希望的那样。 更好的是,定义:

def my_round(x): return int(x + 1) - round(x % 1)
def round5(x): return 5*my_round(x/5)

“修复”round函数并在两行中创建一个漂亮的round5函数。这就是我要做的

def my_round(n):
    lower = (n//5)*5;
    upper = lower+5;

    if (n-lower)<(upper-n):
        return int(lower)
    return int(upper)

print(my_round(703.021))

上面的程序试图找出给定数字前后5的正确倍数。 然后,它找到上下可能数之间的差异,并返回差异最小的数。这等于四舍五入

相关问题 更多 >