加减后浮点数不等于比较
Floating point less-than-equal comparisons after addition and substraction
有没有"best practice"与浮点数进行一系列的浮点算术运算后进行小于等于比较?
我在 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
这是"best practice"吗?如果是,是否有关于如何选择的指南some_arbitrary_factor
?
我的具体问题是我有时间段 (t_0, t_1], (t_1, t_2], ...
并且需要找出给定观察值 x
所在的时间段。x
可能已设置为boundaries t_i
在经历了一系列浮点算术运算之后,如果执行了精确的运算,应该会导致 t_i
。
不,没有最佳实践。不幸的是,不可能,因为几乎所有的浮点计算都会引入一些舍入误差,并且误差的后果对于不同的应用程序是不同的。
通常,软件会执行一些计算,理想情况下会产生一些精确的数学结果 x 但是,由于舍入误差(或其他问题),会产生一个近似值 x'。在比较浮点数时,你想问一些关于 x 的问题,比如“Is x < 1?”或“x = 3.1415926……吗?”所以你要解决的问题是“我如何使用 x' 来回答这个关于 x 的问题?”
对此没有通用的解决方案。即使 x 小于 1,某些错误可能会产生大于 1 的 x'。某些错误可能会产生 x' 小于 1,即使 x 大于 1。任何特定实例中的解决方案都取决于有关在计算 x' 和要回答的具体问题。
有时,彻底的分析可以证明某些关于 x 的问题可以使用 x' 来回答。例如,在某些情况下,我们可能会精心计算,以便我们知道,如果 x' < 1,则 x < 1。或者也许即,如果 x' < .99875,则 x < 1。假设我们分析用于计算 x[ 的计算=47=]' 可以证明最终的误差小于.00125。然后,如果 x' < .99875,那么我们知道 x < 1,并且,如果 x ' > 1.00125,那么 x > 1。但是,如果 .99875 < x' < 1.00125,那么我们不知道是否 x > 1 或 x < 1. 在这种情况下我们该怎么办?对于您的应用程序来说,选择 x < 1 的路径还是 x > 1 的路径更好?答案是针对每个应用程序的,没有通用的最佳实践。
我还要补充一点,发生的舍入误差量因应用程序而异。这是因为舍入误差可以通过多种方式复合。一些具有少量浮点运算的应用程序将获得具有小错误的结果。一些具有许多浮点运算的应用程序也将获得具有适度错误的结果。但某些行为可能导致计算误入歧途并产生灾难性错误。所以处理舍入误差是每个程序的自定义问题。
有没有"best practice"与浮点数进行一系列的浮点算术运算后进行小于等于比较?
我在 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
这是"best practice"吗?如果是,是否有关于如何选择的指南some_arbitrary_factor
?
我的具体问题是我有时间段 (t_0, t_1], (t_1, t_2], ...
并且需要找出给定观察值 x
所在的时间段。x
可能已设置为boundaries t_i
在经历了一系列浮点算术运算之后,如果执行了精确的运算,应该会导致 t_i
。
不,没有最佳实践。不幸的是,不可能,因为几乎所有的浮点计算都会引入一些舍入误差,并且误差的后果对于不同的应用程序是不同的。
通常,软件会执行一些计算,理想情况下会产生一些精确的数学结果 x 但是,由于舍入误差(或其他问题),会产生一个近似值 x'。在比较浮点数时,你想问一些关于 x 的问题,比如“Is x < 1?”或“x = 3.1415926……吗?”所以你要解决的问题是“我如何使用 x' 来回答这个关于 x 的问题?”
对此没有通用的解决方案。即使 x 小于 1,某些错误可能会产生大于 1 的 x'。某些错误可能会产生 x' 小于 1,即使 x 大于 1。任何特定实例中的解决方案都取决于有关在计算 x' 和要回答的具体问题。
有时,彻底的分析可以证明某些关于 x 的问题可以使用 x' 来回答。例如,在某些情况下,我们可能会精心计算,以便我们知道,如果 x' < 1,则 x < 1。或者也许即,如果 x' < .99875,则 x < 1。假设我们分析用于计算 x[ 的计算=47=]' 可以证明最终的误差小于.00125。然后,如果 x' < .99875,那么我们知道 x < 1,并且,如果 x ' > 1.00125,那么 x > 1。但是,如果 .99875 < x' < 1.00125,那么我们不知道是否 x > 1 或 x < 1. 在这种情况下我们该怎么办?对于您的应用程序来说,选择 x < 1 的路径还是 x > 1 的路径更好?答案是针对每个应用程序的,没有通用的最佳实践。
我还要补充一点,发生的舍入误差量因应用程序而异。这是因为舍入误差可以通过多种方式复合。一些具有少量浮点运算的应用程序将获得具有小错误的结果。一些具有许多浮点运算的应用程序也将获得具有适度错误的结果。但某些行为可能导致计算误入歧途并产生灾难性错误。所以处理舍入误差是每个程序的自定义问题。