以下randn
函数用于生成随机数,但是我想知道它是如何工作的。在那里的循环中发生了什么,以及它如何影响所得的随机值?
int rand2() {
return rand() & 1;
}
int randn(int N) {
int add = 0;
int ref = 1;
for (int i = 0; i < N; i++) {
add = add + rand2() * ref;
ref = ref * 2;
}
return add % N;
}
int main() {
srand(time(NULL));
printf("%d, ", randn(5));
return 0;
}
答案 0 :(得分:2)
rand2
生成0
或1
,因此是一个随机位生成器。
randn
使用rand2
,并以二进制方式执行此操作。因此,使用输入N
(它是二进制值的长度),它为每个数字获取一些随机位。但是,该值会在每次迭代结束时转换为十进制。
使用N = 5
;
rand2
返回0
,ref=1
,add=0
(二进制为0
)rand2
返回1
,ref=2
,add=2
(二进制为10
)rand2
返回1
,ref=4
,add=6
(二进制为110
)rand2
返回0
,ref=8
,add=6
(二进制为0110
)rand2
返回1
,ref=16
,add=22
(二进制为10110
) ref
根据数字控制二进制到十进制的转换,其值为ref = 2^i
。在所有迭代中,其值均表示二进制中其各自位置的1
位的值,因此在二进制中为place value。当rand2
结果为1
时,将ref
的值添加到add
的值中,而当rand2
结果为0
时,{{1 }}被忽略,并且ref
的值保持不变。
但是最后,add
返回randn
,即add % N
,因此首先生成随机数的二进制长度22 % 5 = 2
,然后使用相同的长度再次在N
之间获得一个随机值,范围为0 to 4
。生成随机数的某种怪异方法将随机化的按位值生成及其减少到较小范围与最终模数相结合。