What is the correct/standard way to check if difference is smaller than machine precision?

前端 未结 2 1029
野趣味
野趣味 2021-02-01 14:48

I often end up in situations where it is necessary to check if the obtained difference is above machine precision. Seems like for this purpose R has a handy variable: .Mac

2条回答
  •  被撕碎了的回忆
    2021-02-01 15:02

    Definition of a machine.eps: it is the lowest value eps for which 1+eps is not 1

    As a rule of thumb (assuming a floating point representation with base 2):
    This eps makes the difference for the range 1 .. 2,
    for the range 2 .. 4 the precision is 2*eps
    and so on.

    Unfortunately, there is no good rule of thumb here. It's entirely determined by the needs of your program.

    In R we have all.equal as a built in way to test approximate equality. So you could use maybe something like (x)

    i <- 0.1
     i <- i + 0.05
     i
    if(isTRUE(all.equal(i, .15))) { #code was getting sloppy &went to multiple lines
        cat("i equals 0.15\n") 
    } else {
        cat("i does not equal 0.15\n")
    }
    #i equals 0.15
    

    Google mock has a number of floating point matchers for double precision comparisons, including DoubleEq and DoubleNear. You can use them in an array matcher like this:

    ASSERT_THAT(vec, ElementsAre(DoubleEq(0.1), DoubleEq(0.2)));
    

    Update:

    Numerical Recipes provide a derivation to demonstrate that using a one-sided difference quotient, sqrt is a good choice of step-size for finite difference approximations of derivatives.

    The Wikipedia article site Numerical Recipes, 3rd edition, Section 5.7, which is pages 229-230 (a limited number of page views is available at http://www.nrbook.com/empanel/).

    all.equal(target, current,
               tolerance = .Machine$double.eps ^ 0.5, scale = NULL,
               ..., check.attributes = TRUE)
    

    These IEEE floating point arithmetic is a well known limitation of computer arithmetic and is discussed in several places:

    • The FAQ in R has a whole question dedicated to it: R FAQ 7.31
      • The R Inferno by Patrick Burns dedicated the first "Circle" to this problem (page 9 onward)
      • Arithmetic Sum Proof Problem asked in Math Meta
      • David Goldberg, "What Every Computer Scientist Should Know About Floating-point Arithmetic," ACM Computing Surveys 23, 1 (1991-03), 5-48 doi>10.1145/103162.103163 (revision also available)
      • The Floating-Point Guide - What Every Programmer Should Know About Floating-Point Arithmetic
      • 0.30000000000000004.com compares floating point arithmetic across programming languages
    • Canonical duplicate for "floating point is inaccurate" (a meta discussion about a canonical answer for this issue)
    • Several Stack Overflow questions including
      • Why can't decimal numbers be represented exactly in binary?
      • Why are floating point numbers inaccurate?
      • Is floating point math broken?
    • Math Tricks Explained by Arthur T. Benjamin

    . dplyr::near() is another option for testing if two vectors of floating point numbers are equal.

    The function has a built in tolerance parameter: tol = .Machine$double.eps^0.5 that can be adjusted. The default parameter is the same as the default for all.equal().

提交回复
热议问题