0

I have been trying to make a contribution to the data.table package by adding the round function to the ITime class, when i came across a rather odd discrepancy produced by the round function. Behind the scenes, an object of class ITime is just an integer vector with pretty formatting, and thus unclass(object) provides an integer vector.

Rounding this integer vector to the nearest minute can thus be done like this:

x <- as.ITime(seq(as.POSIXct("2020-01-01 07:00:00"), as.POSIXct("2020-01-01 07:10:00"), "30 sec"))

round(unclass(x) / 60L) * 60L
# or 
round(as.integer(x) / 60L) * 60L

Here is where the problem comes...

When I do this operation, I would expect any instance of unclass(x) / 60 that ends with .5 to be rounded up. However, that is not the case!

enter image description here

I have tried the example on both Windows and Mac on two different computers with the same result. Does anyone have an idea as to why this would happen?

** FYI I know that this particular problem can be solved differently: unclass(x) %/% 60L. But my interest is in why the round function does not work as expected.

Jaap
  • 81,064
  • 34
  • 182
  • 193
JPM
  • 144
  • 9

1 Answers1

6

?round:

‘round’ rounds the values in its first argument to the specified
 number of decimal places (default 0).  See ‘Details’ about “round
 to even” when rounding off a 5.

[...]

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’).
alan ocallaghan
  • 3,116
  • 17
  • 37