以下功能应该将给定的数字限制到最近的步骤:
def ceil_step(x, step):
return math.ceil(x / step) * step
此方法运作良好,直到无效:
print(ceil_step(1000.365, 0.01)) # 1000.37
print(ceil_step(1000.369, 0.01)) # 1000.37
print(ceil_step(1000.370, 0.01)) # 1000.37
print(ceil_step(1000.371, 0.01)) # 1000.38
print(ceil_step(10000.365, 0.01)) # 10000.37
print(ceil_step(10000.369, 0.01)) # 10000.37
print(ceil_step(10000.370, 0.01)) # 10000.380000000001
print(ceil_step(10000.371, 0.01)) # 10000.380000000001
有效的实施方案将是:
def ceil_step(x, step):
return Decimal(str(x)).quantize(Decimal(str(step)), rounding=ROUND_CEILING)
[不幸的是,因为我正在编写Numba加速的Python代码,所以无法使用它。因此,我的问题是:有没有一种方法可以实现ceil_step
(和类似的floor_step
)函数,使其仅使用基本浮点运算或Numba支持的函数调用并产生可靠的结果?
现在,我已经解决了以下功能:
def round_step(x, step, method=-1):
eps = np.finfo(np.float64).eps
digits = math.ceil(-np.log10(step))
return round(math.ceil(x * (1 - eps) / step) * step, digits)
与(1 - eps)
的乘积确保(希望!)确保math.ceil
不会过冲。要清除round
之类的内容,必须使用...0000000001
。