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 $.
不,没有最好的做法.不幸的是,不可能,因为几乎所有的浮点计算都会引入一些舍入误差,并且错误的后果对于不同的应用程序是不同的.
通常,软件将执行一些计算,理想情况下会产生一些精确的数学结果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 的路径?答案是针对每个应用程序的,并且没有一般的最佳实践.
我将补充一点,发生的舍入错误量因应用程序而异.这是因为舍入误差可以以各种方式复合.一些具有少量浮点运算的应用程序将获得具有小错误的结果.一些具有许多浮点运算的应用程序也将获得具有适度错误的结果.但某些行为会导致计算误入歧途并产生灾难性错误.因此,处理舍入误差是每个程序的自定义问题.