From emil@bode @ending from d@n@@kn@w@nl  Fri Aug 31 15:45:49 2018
From: emil@bode @ending from d@n@@kn@w@nl (Emil Bode)
Date: Fri, 31 Aug 2018 13:45:49 +0000
Subject: [Rd] compairing doubles
In-Reply-To: <CALEXWq3wSS4uaYu33oA-KUu7gSBuqKYF0ESemwvsbmp6KktOJg@mail.gmail.com>
References: <AM0PR0502MB387404BC690F9AF421B6F5EAD6080@AM0PR0502MB3874.eurprd05.prod.outlook.com>
 <CALEXWq3wSS4uaYu33oA-KUu7gSBuqKYF0ESemwvsbmp6KktOJg@mail.gmail.com>
Message-ID: <95F39593-22F4-46B6-A766-8FF60F608C0C@dans.knaw.nl>

Agreed that's it's rounding error, and all.equal would be the way to go.
I wouldn't call it a bug, it's simply part of working with floating point numbers, any language has the same issue.

And while we're at it, I think the function can be a lot shorter:
.is_continous_evenly_spaced <- function(n){
  length(n)>1 && isTRUE(all.equal(n[order(n)], seq(from=min(n), to=max(n), length.out = length(n))))
}

Cheers, Emil

    El vie., 31 ago. 2018 a las 15:10, Felix Ernst
    (<felix.gm.ernst at outlook.com>) escribi?:
    >
    > Dear all,
    >
    > I a bit unsure, whether this qualifies as a bug, but it is definitly a strange behaviour. That why I wanted to discuss it.
    >
    > With the following function, I want to test for evenly space numbers, starting from anywhere.
    >
    > .is_continous_evenly_spaced <- function(n){
    >   if(length(n) < 2) return(FALSE)
    >   n <- n[order(n)]
    >   n <- n - min(n)
    >   step <- n[2] - n[1]
    >   test <- seq(from = min(n), to = max(n), by = step)
    >   if(length(n) == length(test) &&
    >      all(n == test)){
    >     return(TRUE)
    >   }
    >   return(FALSE)
    > }
    >
    > > .is_continous_evenly_spaced(c(1,2,3,4))
    > [1] TRUE
    > > .is_continous_evenly_spaced(c(1,3,4,5))
    > [1] FALSE
    > > .is_continous_evenly_spaced(c(1,1.1,1.2,1.3))
    > [1] FALSE
    >
    > I expect the result for 1 and 2, but not for 3. Upon Investigation it turns out, that n == test is TRUE for every pair, but not for the pair of 0.2.
    >
    > The types reported are always double, however n[2] == 0.1 reports FALSE as well.
    >
    > The whole problem is solved by switching from all(n == test) to all(as.character(n) == as.character(test)). However that is weird, isn?t it?
    >
    > Does this work as intended? Thanks for any help, advise and suggestions in advance.
    
    I guess this has something to do with how the sequence is built and
    the inherent error of floating point arithmetic. In fact, if you
    return test minus n, you'll get:
    
    [1] 0.000000e+00 0.000000e+00 2.220446e-16 0.000000e+00
    
    and the error gets bigger when you continue the sequence; e.g., this
    is for c(1, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7):
    
    [1] 0.000000e+00 0.000000e+00 2.220446e-16 2.220446e-16 4.440892e-16
    [6] 4.440892e-16 4.440892e-16 0.000000e+00
    
    So, independently of this is considered a bug or not, instead of
    
    length(n) == length(test) && all(n == test)
    
    I would use the following condition:
    
    isTRUE(all.equal(n, test))
    
    I?aki
    
    >
    > Best regards,
    > Felix
    >
    >
    >         [[alternative HTML version deleted]]
    >
    > ______________________________________________
    > R-devel at r-project.org mailing list
    > https://stat.ethz.ch/mailman/listinfo/r-devel
    
    
    
    -- 
    I?aki Ucar
    
    ______________________________________________
    R-devel at r-project.org mailing list
    https://stat.ethz.ch/mailman/listinfo/r-devel
    



[Rd] compairing doubles
Emil Bode