1

I have a function that passes a number to different rounding functions depending on a category. For example, if my function is applyRoundRule, and if the category is A, I might pass the number 2.415 to a rounding function that might round up from 5 with the expected result 2.42.

My problem is if I input the number directly into the function call it works fine, but if I pass in a function or variable that determines the number R appears to conduct its own rounding resulting in the wrong result, 2.41 in the above case.

For instance, if I write

applyRoundRule("A", (1 + 15/100)*2.1)

The answer is

2.41

Similarly, if write

applyRoundRule("A", signif((1 + 15/100)*(100 - 97.9),4))

I get the right answer (2.42) but in other instances I get the wrong answer, in other words without signif certain values will be wrong and with another set of numbers will be wrong.

What can I do such that R doesn't conduct it's own rounding prior to my designated rounding rules?

Edit: Please find an example of the two relevant functions

applyRoundRule <- function(categ, num){

  roundVal <- switch(categ,
                       "A" = RoundUp(num,2),
                       "B" = RoundUp(num,3)
  )

  return(roundVal)
}

And the rounding function might be something like

RoundUp = function(x, n) {
  z = abs(x)*10^n
  z = z + 0.5
  z = trunc(z)
  z = z/10^n
}
Celeste
  • 337
  • 4
  • 15
  • Please share your function `applyRoundRule`. –  Oct 01 '15 at 23:10
  • @Pascal please find an example in the edits now – Celeste Oct 01 '15 at 23:25
  • 1
    I don't get it you give an example the doesn't produce the error you describe. They both produce 2.42. Can you provide an instance that produces the error? BTW are you aware of the functions `floor` and `ceiling`? – CCurtis Oct 01 '15 at 23:33
  • 1
    Can't say for sure until you illustrate the problem , but my guess is a floating point accuracy problem, [see this r-faq](http://stackoverflow.com/q/9508518/903061). – Gregor Thomas Oct 01 '15 at 23:38
  • @CCurtis I've changed the example now to better illustrate the problem. In the example I have given using signif fixes it, but as I said in the post, it fails to fix it for other examples. I.e. signif will resolve the issue, but then will cause more instances when it is off by 0.01 – Celeste Oct 01 '15 at 23:43
  • @Gregor the point is the value I am passing in is determined by a function itself, I have tried separating it out and assigning it to a variable but that doesn't resolve the issue. So, the function itself isn't wrong, it does what I want, it's just that I get a different result if I pass in a variable/function as the value as opposed to the actual number – Celeste Oct 01 '15 at 23:45
  • 1
    It's a precision error in floating point arithmetic. Try `(1 + 15/100)*2.1 > (1 + 15/100)*(100 - 97.9)`, I get `TRUE`. You may want to build in some sort of tolerance check where you first round to, say, the nearest `1e-8`, then round up or down from there. See my link above (and the links in it) for more info. – Gregor Thomas Oct 01 '15 at 23:49
  • @Gregor thank you, I'll have a look at the material and post my solution – Celeste Oct 02 '15 at 00:08
  • Or at it's most basic - `2.1 == (100-97.9)` gives `FALSE` - Consider `sprintf("%.16f", 2.1)` vs. `sprintf("%.16f", 100-97.9)` – thelatemail Oct 02 '15 at 00:12

0 Answers0