3

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?

m0nhawk
  • 22,980
  • 9
  • 45
  • 73
Khiem Nguyen
  • 129
  • 1
  • 11

2 Answers2

5

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.

Ben
  • 20,038
  • 30
  • 112
  • 189
-3

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).

Shreyas
  • 999
  • 6
  • 19
  • Your definitions of floor and ceiling are incorrect. See ?floor and ?ceiling – Ben Sep 02 '18 at 04:06
  • Or would it be correct when it said, `floor(x)` function rounds to the smallest integer not less than `x` & `ceiling(x)` function rounds to the largest integer not greater than `x` – Shreyas Sep 02 '18 at 04:13
  • Shreyas you have that backwards. Even if you get the definitions right, I think you're missing the point. Do this.. What do you get in R when you do `ceiling(56)`? Now what is 0.28/0.005? And what do you get when you do `ceiling(0.28/0.005)`? Notice the difference. – Ben Sep 02 '18 at 04:16
  • yeah...got it. so as per your line of code `print(0.28/0.005, digits = 18) # 56.0000000000000071` ceiling of it returns `57` because of the value after the decimal point. Right? – Shreyas Sep 02 '18 at 04:22
  • Also i would like to know, why my regular calculator says `56` and R says `56.0000000000000071`? Is it because of so-called tolerance `.Machine$double.eps ^ 0.5.`? If so, then I need to study `tolerance`. Is it with respect to mathematics/computing? – Shreyas Sep 02 '18 at 04:25