浮点加减后小于等于比较

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

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

我在 R 中有以下示例(尽管该问题适用于任何使用浮点的语言)。我有一个双

x = 1
,我在上面应用了一系列加法和减法。最后
x
应该恰好是 1,但不是由于浮点算术(根据我收集的数据)。这是例子:

> 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
。浮点算术运算,如果执行精确运算,应产生
t_i

r floating-point floating-accuracy epsilon inexact-arithmetic
1个回答
9
投票

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

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

对此没有通用的解决方案。即使 x 小于 1,某些错误也可能会产生大于 1 的 x'。即使 x 大于 1,某些错误也可能会产生小于 1 的 x'。具体实例取决于计算 x' 时生成的错误信息以及要回答的具体问题。

有时,彻底的分析可以证明有关 x 的某些问题可以使用 x' 来回答。例如,在某些情况下,我们可能会精心计算,以便我们知道,如果 x' < 1, then x < 1. Or perhaps that, if x' < .99875, then x < 1. Say we analyze the calculations we used to calculate x' 并且可以显示最终误差小于 0.00125。那么,如果 x' < .99875, then we know x < 1, and, if x' > 1.00125,则 x > 1。但是,如果 .99875 < x' < 1.00125, then we do not know whether x > 1 或 x < 1. What do we do in that situation? Is it then better for your application to take the path where x < 1 or the path where x > 1 ?答案是针对每个应用程序的,没有通用的最佳实践。

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

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