Sim*_*lon 11 random r internals prng
鉴于以下是等价的,我们可以推断R使用相同的C runif
函数来生成sample()
和runif()
...的均匀样本
set.seed(1)
sample(1000,10,replace=TRUE)
#[1] 27 38 58 91 21 90 95 67 63 7
set.seed(1)
ceiling( runif(10) * 1000 )
#[1] 27 38 58 91 21 90 95 67 63 7
Run Code Online (Sandbox Code Playgroud)
但是在处理大数字时,它们并不相同(n > 2^32 - 1
):
set.seed(1)
ceiling( runif(1e1) * as.numeric(10^12) )
#[1] 265508663143 372123899637 572853363352 908207789995 201681931038 898389684968
#[7] 944675268606 660797792487 629114043899 61786270468
set.seed(1)
sample( as.numeric(10^12) , 1e1 , replace = TRUE )
#[1] 2655086629 5728533837 2016819388 9446752865 6291140337 2059745544 6870228465
#[8] 7698414177 7176185248 3800351852
Run Code Online (Sandbox Code Playgroud)
正如@Arun指出第1,第runif()
2,第3 ...... 的第1,第3,第5 ......的近似结果sample()
.
事实证明,这两个函数调用unif_rand()
在幕后,但是sample
,有一个参数,n
比类型的表示的最大整数较大"integer"
,但可表示为一个整数类型"numeric"
使用此静态定义绘制一个随机的偏离(而不是仅仅unif_rand()
作为在...的情况下runif()
...
static R_INLINE double ru()
{
double U = 33554432.0;
return (floor(U*unif_rand()) + unif_rand())/U;
}
Run Code Online (Sandbox Code Playgroud)
在文档中有一个神秘的说明......
两个随机数用于确保大整数的均匀采样.
为什么需要两个随机数来确保大整数的均匀采样?
什么是常数U
,为什么需要特定值33554432.0
?
原因是 25 位 PRNG 无法产生足够的位来生成大于 2^25 范围内的所有可能的整数值。为了给每个可能的整数值赋予非零概率,需要调用 25 位 PRNG 两次。通过两次调用(如您引用的代码中所示),您将获得 50 个随机位。
请注意,adouble
有 53 位尾数,因此调用 PRNG 两次仍然缺少 3 位。