as.integer(x) rounds floating point numbers towards zero, so it behaves approximately as as.integer(trunc(x)). If x > INT_MAX, then as.integer(x) is NA. This is nothing bad, but it is slightly more restrictive than necessary. An alternative approach could be that as.integer(x) is NA, if trunc(x) > INT_MAX and as.integer(x) == INT_MAX for all x in [INT_MAX,INT_MAX+1). Let me suggest the following patch to IntegerFromReal for consideration: --- R-devel_2007-10-11-orig/src/main/coerce.c 2007-07-25 17:54:17.000000000 +0200 +++ R-devel_2007-10-11-asinteger/src/main/coerce.c 2007-10-12 07:10:06.000000000 +0200 @@ -173,7 +173,8 @@ { if (ISNAN(x)) return NA_INTEGER; - else if (x > INT_MAX || x <= INT_MIN ) { + x = trunc(x); + if (x > INT_MAX || x <= INT_MIN ) { *warn |= WARN_NA; return NA_INTEGER; } This patch changes the behavior as suggested above. Its effect may be seen using the script options(digits=12) x <- seq(2^31 - 3, 2^31, length=7) cbind(x,as.integer(trunc(x)),as.integer(x)) Original behavior: [1,] 2147483645.0 2147483645 2147483645 [2,] 2147483645.5 2147483645 2147483645 [3,] 2147483646.0 2147483646 2147483646 [4,] 2147483646.5 2147483646 2147483646 [5,] 2147483647.0 2147483647 2147483647 [6,] 2147483647.5 2147483647 NA [7,] 2147483648.0 NA NA Using the patch: [1,] 2147483645.0 2147483645 2147483645 [2,] 2147483645.5 2147483645 2147483645 [3,] 2147483646.0 2147483646 2147483646 [4,] 2147483646.5 2147483646 2147483646 [5,] 2147483647.0 2147483647 2147483647 [6,] 2147483647.5 2147483647 2147483647 [7,] 2147483648.0 NA NA Petr Savicky.