For-loop vs while loop in R
Because 1
is numeric, but not integer (i.e. it's a floating point number), and 1:6000
is numeric and integer.
> print(class(1))[1] "numeric"> print(class(1:60000))[1] "integer"
60000 squared is 3.6 billion, which is NOT representable in signed 32-bit integer, hence you get an overflow error:
> as.integer(60000)*as.integer(60000)[1] NAWarning message:In as.integer(60000) * as.integer(60000) : NAs produced by integer overflow
3.6 billion is easily representable in floating point, however:
> as.single(60000)*as.single(60000)[1] 3.6e+09
To fix your for
code, convert to a floating point representation:
function (N){ for(i in as.single(1:N)) { y <- i*i }}
The variable in the for loop is an integer sequence, and so eventually you do this:
> y=as.integer(60000)*as.integer(60000)Warning message:In as.integer(60000) * as.integer(60000) : NAs produced by integer overflow
whereas in the while loop you are creating a floating point number.
Its also the reason these things are different:
> seq(0,2,1)[1] 0 1 2> seq(0,2)[1] 0 1 2
Don't believe me?
> identical(seq(0,2),seq(0,2,1))[1] FALSE
because:
> is.integer(seq(0,2))[1] TRUE> is.integer(seq(0,2,1))[1] FALSE
And about timing:
fn1 <- function (N) { for(i in as.numeric(1:N)) { y <- i*i }}fn2 <- function (N) { i=1 while (i <= N) { y <- i*i i <- i + 1 }}system.time(fn1(60000))# user system elapsed # 0.06 0.00 0.07 system.time(fn2(60000))# user system elapsed # 0.12 0.00 0.13
And now we know that for-loop is faster than while-loop. You cannot ignore warnings during timing.