Ceiling function in R is inaccurate (sometimes)

Viewed 1032

I am trying to round up a number x to be divisible by a number m. Using the following function from previous post on SO:

roundUP = function(x,m) 
{
    return(m * ceiling(x/m))
}

But, when I input x = 0.28 and m = 0.005, the function outputs 0.285 when the result should be 0.28.

When I tried ceiling(0.28/0.005) it outputs 57 when the result should be 56 since 56 is already a whole number. Can anyone explain if is this happening and is this an error from Ceiling function?

2 Answers

The issue has to do with floating point arithmetic. You can find some details about this here.

Walk through the code below and it should shed some light on what's going on.

0.28/0.005  # Console displays 56
0.28/0.005 == 56  # returns FALSE. Why?
print(0.28/0.005, digits = 18)  # 56.0000000000000071

# Solution?
roundUP = function(x, m) 
{
  return(m * ceiling(round(x/m, 9)))
}

Also, note the Warning section within ?ceiling

The realities of computer arithmetic can cause unexpected results, especially with floor and ceiling. For example, we ‘know’ that floor(log(x, base = 8)) for x = 8 is 1, but 0 has been seen on an R platform. It is normally necessary to use a tolerance.

In R,

floor(x) function rounds to the nearest integer that’s smaller than x.

ceiling(x) function rounds to the nearest integer that’s larger than x.

So whatever be the value after the decimal point, R considers the next integer (before/after).

If you want 56 as the output, you must use floor(0.28/0.005).

Related