4

I really just want to do something like

x <- as.integer(c(1,2,3))

But because c(1,2,3) is stored as a floating point vector I'm worried that I'll have problems with truncation, such as

> as.integer(1.99999999999)
[1] 1

How do I know I'm safe?

Aaron left Stack Overflow
  • 36,704
  • 7
  • 77
  • 142
Xu Wang
  • 10,199
  • 6
  • 44
  • 78

1 Answers1

10

you can use a suffix L:

> x <- c(1L, 2L, 3L)
> is.integer(x)
[1] TRUE

> x <- 1L:3L
> x
[1] 1 2 3
> is.integer(x)
[1] TRUE

Or if you already have a numeric vector and convert it into integer, you can explicitly describe the rule:

> x <- c(-0.01, 1.999, 2, 3.000001)
> as.integer(round(x))
[1] 0 2 2 3
> as.integer(floor(x))
[1] -1  1  2  3
> as.integer(trunc(x))
[1] 0 1 2 3
> as.integer(ceiling(x))
[1] 0 2 2 4
kohske
  • 65,572
  • 8
  • 165
  • 155
  • As you show, `round` and company return floating point numbers so need to be coerced to integer. Is there any need to worry about that coercion doing something unexpected? – Aaron left Stack Overflow Apr 01 '12 at 01:42
  • What kind of unexpected behavior you think of? – kohske Apr 02 '12 at 09:51
  • Same as above, truncation. Could the result from `round` and the others ever be stored as 1.999999999 (or the binary equivalent) so `as.integer` would return 1 instead of 2? – Aaron left Stack Overflow Apr 02 '12 at 11:57
  • you can find the implementations here: http://svn.r-project.org/R/trunk/src/nmath/fround.c http://svn.r-project.org/R/trunk/src/main/arithmetic.c I think you don't need to worry about that. – kohske Apr 02 '12 at 19:42