加法和减法后浮点数小于等于

Ben*_*sen 1 floating-point r floating-accuracy epsilon inexact-arithmetic

在一系列浮点算术运算之后,是否存在一个"最佳实践",而不是与浮点数相等的比较?

我在R中有以下示例,但该问题不仅适用于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
Run Code Online (Sandbox Code Playgroud)

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

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
Run Code Online (Sandbox Code Playgroud)

这是"最佳实践",如果有,是否有如何选择的指导方针 some_arbitrary_factor

我的具体问题是我有时间段$(t_0,t_1),(t_1,t_2),\ dots $并且需要找出给定观察$ x $所在的时间段.$ x $可能已被设置为一个边界$ t_i $经过一系列浮点算术运算后,如果执行了精确的运算,应该得到$ t_i $.

Eri*_*hil 5

不,没有最好的做法.不幸的是,不可能,因为几乎所有的浮点计算都会引入一些舍入误差,并且错误的后果对于不同的应用程序是不同的.

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

对此没有通用的解决方案.某些错误可能会产生一个X "大于1,即使X小于1.一些错误可能会产生一个X "是小于1,即使x是大于1的任何特定实例中的解决方案取决于有关更大计算x '时产生的错误和要回答的具体问题.

有时,彻底的分析可以证明可以使用x ' 回答关于x的某些问题.例如,在某些情况下,我们可能会进行计算,以便我们知道,如果x '<1,那么x <1.或许,如果x '<.99875,那么x <1.假设我们分析计算我们用于计算x '并且可以显示最终误差小于.00125.然后,如果x '<.99875,那么我们知道x <1,如果x '> 1.00125,则x > 1.但是,如果.99875 < x '<1.00125,那么我们不知道x > 1还是x <1.在那种情况下我们该怎么做?您的应用程序是否更好地采用x <1的路径或x > 1 的路径?答案是针对每个应用程序的,并且没有一般的最佳实践.

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