pomber
pomber

Reputation: 23980

Fix floating point imprecision in ceiling

The problem:

ceiling(31)
#31
ceiling(31/60*60)
#32

What is the correct way to fix this kind of errors?

Doing the multiplication before the division is not an option, my code looks something like this:

x <- 31/60
...
y <- ceiling(x*60)

I'm thinking of doing a new function:

ceil <- function(x) {
  ceiling(signif(x))
}

But I'm new to R, maybe there is a better way.

UPDATE
Sorry, I didn't give more details, I have the same problem in different parts of my code for different reasons, but always with ceiling.

I am aware of the rounding error in floating-point calculation. Maybe the title of the question could be improved, I don't want to fix an imprecision of the ceiling function, what I want to do is perhaps the opposite, make ceiling less exact. A way to tell R to ignore the digits that are clearly noise:

options(digits=17)
31/60*60
#31.000000000000004

But, apparently, the epsilon required to ignore the noise digits depends on the context of the problem.

Upvotes: 5

Views: 610

Answers (1)

Carl Witthoft
Carl Witthoft

Reputation: 21502

The real problem here, I strongly believe, is found in my hero The Data Munger Guru's tagline, which is: "What is the problem that you are trying to solve? Tell me what you want to do, not how you want to do it. "

There are myriad cases where floating-point precision will cause apparent integers to turn into "integer +/- epsilon" , and so you need to figure out why you are going for "ceiling" , why you allow your values to not be integers, etc. <-- more or less what Pascal Cuoq wrote in his comment.

The solution to your concern thus depends on what's actually going on. Perhaps you want, say trunc(x/60)->y followed with trunc(y*60) , or maybe not :-) . Maybe you want y<-round(x/60*60) +1 , or jhoward's suggested approach. It depends, as I stress here, critically on what your goal is and how you want to deal with corner cases.

Upvotes: 1

Related Questions