4

I understand that the round function in R does not always round up with .5, that's why the following code:

x <- seq(0.5, 9.5, by=1)
#[1] 0.5 1.5 2.5 3.5 4.5 5.5 6.5 7.5 8.5 9.5
round(x, 0)

results in 0, 2, 2, 4, 4..., instead of 1, 2, 3, 4, 5...

However, when I used the following numbers:

y <- seq(105.405, 105.505, .01)
#[1] 105.405 105.415 105.425 105.435 105.445 105.455 105.465 105.475 105.485 105.495 105.505
round(y, 2)

it showed the following results:

[1] 105.40 105.42 105.42 105.44 105.45 105.46 105.47 105.47 105.48 105.50 105.50

which it sometimes round to 5 or 7.

Does anyone know what the problem is and how to fix it? Is there any update or package that fixes the problem or do we have to write our own function?

Jord_O
  • 41
  • 2
  • 4
    Floating point arithmetic is not exact. – Tim Biegeleisen Jun 30 '20 at 03:52
  • It uses the `uncomon` rounding procedure that is taught is school. If 5 is proceeded by a odd number, then round up, while if it is proceeded by an even number, you do not round up. – Onyambu Jun 30 '20 at 03:55
  • 2
    @Onyambu The OP's issue here is likely imprecision due to floating point numbers not being exactly represented in R code. – Tim Biegeleisen Jun 30 '20 at 03:58
  • 2
    Relevant: [Why are these numbers not equal?](https://stackoverflow.com/questions/9508518/why-are-these-numbers-not-equal) – markus Jun 30 '20 at 04:31

1 Answers1

3

The problem is that the number you see represented is not the number actually stored. From the R documentation:

Note that for rounding off a 5, the IEC 60559 standard (see also ‘IEEE 754’) is expected to be used, ‘go to the even digit’. Therefore round(0.5) is 0 and round(-1.5) is -2. However, this is dependent on OS services and on representation error (since e.g. 0.15 is not represented exactly, the rounding rule applies to the represented number and not to the printed number, and so round(0.15, 1) could be either 0.1 or 0.2).

Igor Rivin
  • 4,632
  • 2
  • 23
  • 35
  • 1
    Thanks! I think I read the first half from ?round, but did not notice the second half of it. – Jord_O Jun 30 '20 at 05:00