使用浮点数时避免不准确?

时间:2016-01-18 22:08:34

标签: python python-2.7 python-3.x floating-accuracy

我尝试使用蒙特卡洛积分来近似给定图形下的区域来计算其面积。为此,我需要计算出的y_min和y_max是准确的。因此,作为示例,我将使用从0到pi的sin(x)图表。要找到y_min和y_max,我有以下功能:

def y_range(f, x_min, x_max, n=100):
    # Step size
    h = float((x_max - x_min)) / n

    # Calculate y for n points between x_min and x_max
    y = [f(x * h) for x in range(0, n + 1)]

    # Get minimum and maximum y
    y_max = max(y)
    y_min = min(y)

    return y_min, y_max

打印y_min和y_max给出:

y_max = 1.0
y_min = -3.21624529935e-16

我知道y_min应该等于0.0,那么如何纠正这种不准确性?

3 个答案:

答案 0 :(得分:1)

根本问题是,对于任何maxmin + 100*h无法导出h。有几个潜在的原因,但最简单的原因就是它们之间的步数不能被100整除。

如何更好地完成它取决于你想要多么谨慎。您需要的两件事就是在两个值之间进行插值(而不是基于起点和步骤),并以精确的方式执行插值。

以下代码将产生可靠的结果:

def interp_at_step(a, b, i, n):
    # separate calculation of alpha and beta to avoid catastrophic cancellation
    alpha = (n-i)/n
    beta = i/n
    return a*alpha + b*beta

def y_range(f, x_min, x_max, n=100):
    # Calculate y for n points between x_min and x_max
    y = [f(interp_at_step(x_min, x_max, x, n)) for x in range(0, n + 1)]

    # Get minimum and maximum y
    y_max = max(y)
    y_min = min(y)

    return y_min, y_max

当然,正如Denys所说,pi无法准确表现出来。因此,这将减轻插值的误差,但不一定来自操作数本身。

答案 1 :(得分:0)

pi是不合理的,所以你必须接受它只能以一定的精度表示,无论你使用哪种表示。如果您正在使用float,那么精度将按照id product ------ --------- 155535 OTC 155535 COM 155536 OTC 155537 COM 155538 UNKNOWN 的顺序排列here。最简单的方法是使用10**(-16)将结果四舍五入到15位小数。如果您需要比15位十进制数更好的精度,您可能会考虑其他类型来表示变量,例如十进制

答案 2 :(得分:-1)

当精度如此重要时,我不会使用float。我建议你看看decimal.Decimal。假设您将x_minx_max更改为十进制,则只需在第3行删除float

This帖子可能有助于解释不准确的来源: