R 中的 For 循环与 while 循环 [英] For-loop vs while loop in R
问题描述
我在 R 中工作时注意到一件奇怪的事情.当我有一个使用 for-loop 和 while-loop 实现的计算从 1 到 N 的平方的简单程序时,行为是不一样的.(在这种情况下,我不关心矢量化或应用函数).
I have noticed a curious thing whilst working in R. When I have a simple program that computes squares from 1 to N implemented using for-loop and while-loop the behaviour is not the same. (I don't care about vectorisation in this case or apply functions).
fn1 <- function (N)
{
for(i in 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
2.500 0.012 2.493
There were 50 or more warnings (use warnings() to see the first 50)
Warning messages:
1: In i * i : NAs produced by integer overflow
.
.
.
system.time(fn2(60000))
user system elapsed
0.138 0.000 0.137
现在我们知道 for 循环更快了,我猜是因为那里有预分配和优化.但是为什么会溢出呢?
Now we know that for-loop is faster, my guess is because of pre allocation and optimisations there. But why does it overflow?
更新:所以现在尝试使用向量的另一种方式:
UPDATE: So now trying another way with vectors:
fn3 <- function (N)
{
i <- 1:N
y <- i*i
}
system.time(fn3(60000))
user system elapsed
0.008 0.000 0.009
Warning message:
In i * i : NAs produced by integer overflow
所以也许它是一个时髦的内存问题?我在具有 4Gb 内存和 R 中所有默认设置的 OS X 上运行.这发生在 32 位和 64 位版本中(除了时间更快).
So Perhaps its a funky memory issue? I am running on OS X with 4Gb of memory and all default settings in R. This happens in 32- and 64-bit versions (except that times are faster).
亚历克斯
推荐答案
因为 1
是数字,但不是整数(即它是一个浮点数),并且 1:6000
是数字和整数.
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 平方是 36 亿,不能用有符号的 32 位整数表示,因此会出现溢出错误:
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] NA
Warning message:
In as.integer(60000) * as.integer(60000) : NAs produced by integer overflow
36 亿很容易用浮点数表示,但是:
3.6 billion is easily representable in floating point, however:
> as.single(60000)*as.single(60000)
[1] 3.6e+09
要修复您的 for
代码,请转换为浮点表示:
To fix your for
code, convert to a floating point representation:
function (N)
{
for(i in as.single(1:N)) {
y <- i*i
}
}
这篇关于R 中的 For 循环与 while 循环的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!