【问题标题】:Floating point less-than-equal comparisons after addition and substraction加减法后的浮点数小于等于比较
【发布时间】:2018-03-26 03:50:10
【问题描述】:

在一系列浮点算术运算之后与浮点数进行小于等于比较是否有“最佳实践”?

我在 R 中有以下示例(尽管该问题适用于任何使用浮点的语言)。我有一个双 x = 1,我在上面应用了一系列的加法和减法。最后x 应该正好是一,但不是由于浮点运算(据我收集)。示例如下:

> stop_times <- seq(0.25, 2, by = .25)
> expr <- expression(replicate(100,{
    x <- 1

    for(i in 1:10) {
      tmp <- rexp(1, 1)
      n <- sample.int(1e2, 1)
      delta <- tmp / n
      for(j in 1:n)
        x <- x - delta
      x <- x + tmp
    }

    # "correct" answer is 4  
    which.max(x <= stop_times)
  }))
> eval(expr)
  [1] 5 5 5 4 4 4 5 5 5 4 5 4 4 4 5 5 4 4 5 4 5 4 5 4 5 5 5 4 4 4 4 4 4 4 4 4 5 5 5 5 5 4 5 4 5 5 5 4 4 5 5 5 4 4 5 5 5 4 4 4 4 4 4
 [64] 5 4 4 4 5 5 5 4 4 4 5 4 4 4 4 4 4 4 4 5 5 5 5 4 4 4 5 5 5 5 5 4 4 4 5 5 4

一个(天真的?)解决方案是在不等式的右侧添加一些任意小的正数,如下所示

some_arbitrary_factor <- 100
stop_times <- seq(0.25, 2, by = .25) + 
  some_arbitrary_factor * .Machine$double.eps
eval(expr)
  [1] 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4
 [64] 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4

这是“最佳实践”吗?如果是,是否有关于如何选择 some_arbitrary_factor 的指南?

我的具体问题是我有时间段(t_0, t_1], (t_1, t_2], ... 并且需要找出给定观察x 所处的时间段。x 在经历了一系列浮点算术运算,如果执行精确运算,则应返回 t_i

【问题讨论】:

  • 如果您想更详细地了解这一点,Donald knuth 的计算机编程艺术,第 3 章很好地概述了浮点的黑魔法。在 R 中,我们有 all.equal 作为测试近似相等性的内置方法。所以你可以使用类似(x&lt;y) | all.equal(x,y)
  • 我知道all.equal 函数。默认值是 scale = NULL(默认值)的数值比较通常在相对差异尺度上,除非目标值接近于零:首先,计算两个数值向量的平均绝对差值。如果这小于容差或不是有限的,则使用绝对差,否则按平均绝对目标值缩放相对差。 其中tolerance 默认为sqrt(.Machine$double.eps)。我不确定这是否是一种常见做法?

标签: r floating-point floating-accuracy epsilon inexact-arithmetic


【解决方案1】:

不,没有最佳实践。不幸的是,不可能有,因为几乎所有的浮点计算都会引入一些舍入误差,并且对于不同的应用,误差的后果是不同的。

通常,软件会执行一些计算,理想情况下会产生一些精确的数学结果x,但由于舍入误差(或其他问题),会产生近似值x' .在比较浮点数时,您想问一些关于 x 的问题,例如“x x = 3.1415926...?”所以你要解决的问题是“我如何使用x'来回答这个关于x的问题?”

对此没有通用的解决方案。即使 x 小于 1,某些错误可能会产生大于 1 的 x'。某些错误可能会产生大于 1 的 x'小于 1,即使 x 大于 1。任何特定情况下的解决方案都取决于在计算 x' 时生成的错误信息以及要回答的具体问题。

有时,彻底的分析可以证明有关 x 的某些问题可以使用 x' 来回答。例如,在某些情况下,我们可能会精心计算,以便知道,如果 x' x x' x x' 的计算,可以证明最终的误差小于.00125。那么,如果 x' x x' > 1.00125,那么 x > 1. 但是,如果.99875 x' x > 1还是x x x > 1 的路径更好?答案是针对每个应用程序的,没有通用的最佳实践。

我还要补充一点,发生的舍入误差量因应用程序而异。这是因为舍入误差可以以多种方式复合。一些具有少量浮点运算的应用程序将获得具有小错误的结果。一些具有许多浮点运算的应用程序也将获得适度错误的结果。但是某些行为可能会导致计算误入歧途并产生灾难性错误。所以处理舍入误差是每个程序的自定义问题。

【讨论】:

  • 这就是我的想法。不过,确认一下就好了。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-06-23
  • 2020-04-22
相关资源
最近更新 更多