快速精确的最近步浮点上限/无小数位数的地板

问题描述 投票:0回答:1

以下功能应该将给定的数字限制到最近的步骤:

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支持的函数调用并产生可靠的结果?

python numpy floating-point ieee-754 numba
1个回答
0
投票

现在,我已经解决了以下功能:

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

© www.soinside.com 2019 - 2024. All rights reserved.