【问题标题】:Avoiding inaccuracy when using floating points numbers?使用浮点数时避免不准确?
【发布时间】:2016-04-24 05:28:14
【问题描述】:

我正在尝试使用蒙特卡洛积分来近似给定图表下的区域以计算其面积。为此,我需要计算出的 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,那么我该如何纠正这种不准确性?

【问题讨论】:

  • 真的很接近为零...

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


【解决方案1】:

根本问题是max 不能作为min + 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 无法精确表示。所以这将减少插值产生的错误,但不一定是操作数本身的错误。

【讨论】:

    【解决方案2】:

    pi 是非理性的,因此无论您使用哪种表示,您都必须接受它只能以一定的精度表示。如果您使用浮点数,则精度将按照10**(-16) 的顺序排列,如here 所述。一个最简单的方法是使用round(value,15) 将结果四舍五入为 15 位小数。如果您需要比 15 位十进制数字更高的精度,您确实可以考虑使用其他类型来表示变量,例如十进制

    【讨论】:

      【解决方案3】:

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

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

      【讨论】:

      • decimal.Decimal 不会帮助您准确表示 pi。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-11-26
      • 1970-01-01
      • 2017-06-08
      • 2015-09-07
      • 2011-01-07
      • 1970-01-01
      相关资源
      最近更新 更多