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

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

问题描述

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

我在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在经历了a之后可能已设置为边界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 的问题,例如是 x < 1?"或" 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 '.有些错误可能会产生 x '即使x大于1,也应小于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 '的计算,并且可以证明最终误差小于.00125.然后,如果 x '< .99875,那么我们知道 x < 1,如果 x '> 1.00125,则 x >1.但是,如果.99875< x '< 1.00125,那么我们不知道 x > 1还是 x < 1.在那种情况下我们该怎么办?那么您的应用程序采用 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天全站免登陆