加减法后的浮点数小于等于比较 [英] Floating point less-than-equal comparisons after addition and substraction

查看:27
本文介绍了加减法后的浮点数小于等于比较的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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

I have the following example in R (although the question applies to any language using floating-point). I have a double x = 1 on which I apply a series of additions and subtractions. In the end x should be exactly one but is not due to floating-point arithmetic (from what I gather). Here is the example:

> 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

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

A (naive?) solution is to add some arbitrary small positive number to the right hand side of the inequality as follows

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 的指南?

Is this "best practice" and if so are there guidelines on how to chose some_arbitrary_factor?

我的具体问题是我有时间段 (t_0, t_1], (t_1, t_2], ... 并且需要找出给定观察的时间段 x 在其中.在经历了一系列浮点算术运算后,可能已将 x 设置为边界 t_i ,这将导致 t_i 如果执行了确切的操作.

My concrete problem is that I have time periods (t_0, t_1], (t_1, t_2], ... and need to find out in which period a given observation x is in. x may have been set to one the boundaries t_i after having undergone a series of floating-point arithmetic operations which should result in t_i if exact operation where performed.

推荐答案

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

No, there is no best practice. Unfortunately, there cannot be, because almost all floating-point calculations introduce some rounding error, and the consequences of the errors are different for different applications.

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

Typically, software will perform some calculations that ideally would yield some exact mathematical result x but, due to rounding errors (or other issues), produce an approximation x'. When comparing floating-point numbers, you want to ask some question about x, such as "Is x < 1?" or "Is x = 3.1415926…?" So the problem you want to solve is "How do I use x' to answer this question about x?"

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

There is no general solution for this. Some errors may produce an x' that is greater than 1 even though x is less than 1. Some errors may produce an x' that is less than 1 even though x is greater than 1. The solution in any specific instance depends on information about the errors that were generated while calculating x' and the specific question to be answered.

有时,彻底的分析可以证明关于 x 的某些问题可以使用 x' 来回答.例如,在某些情况下,我们可能会精心计算,以便我们知道,如果 x' <1,然后 x <1. 或者,如果 x' <.99875,然后 x <1. 假设我们分析了我们用来计算 x' 的计算,并且可以显示最终误差小于 0.00125.那么,如果 x' <.99875,那么我们知道 x <1,并且,如果 x' > 1.00125,则 x > 1.但是,如果 .99875 <x' <1.00125,那么我们不知道是x > 1还是x x1. 在那种情况下我们该怎么办?那么你的应用程序走 x < 的路径会更好吗?1 还是 x > 1 的路径?答案是针对每个应用程序的,没有通用的最佳实践.

Sometimes a thorough analysis can demonstrate that certain questions about x can be answered using x'. For example, in some situations, we might craft calculations so that we know that, if x' < 1, then x < 1. Or perhaps that, if x' < .99875, then x < 1. Say we analyze the calculations we used to calculate x' and can show that the final error is less than .00125. Then, if x' < .99875, then we know x < 1, and, if x' > 1.00125, then x > 1. But, if .99875 < x' < 1.00125, then we do not know whether x > 1 or 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? The answer is specific to each application, and there is no general best practice.

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

I will add to this that the amount of rounding error that occurs varies hugely from application to application. This is because rounding error can be compounded in various ways. Some applications with a few floating-point operations will achieve results with small errors. Some applications with many floating-point operations will also achieve results with modest errors. But certain behaviors can lead calculations astray and produce catastrophic errors. So dealing with rounding error is a custom problem for each program.

这篇关于加减法后的浮点数小于等于比较的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆