使用rand函数时发现,产生的随机数有相同的规律。查了一下才发现有真假随机数之分,好奇是什么导致了rand函数生成的是假随机数,而srand的是真随机数?
题主貌似搞错了 srand 的功能了,这个函数用来设置随机数的种子,并不是用来生成随机数的。在种子确定的情况下,不断调用 rand 产生的值序列就是确定,这就是伪随机。
srand
rand
所谓真随机,完全不可预测的随机数,一般都是要读取一些外部设备的白噪声来获得随机数,比如耳机输入口的噪声,或者网卡接口的噪声等。*nix 系统里面有个 /dev/random 就是用来产生这种真随机数的。
/dev/random
真随机是无法通过某个固定算法来模拟的,因为一旦有了固定算法,随机序列就可以被预测,它就不算真随机了。
刚才去看了 php 的源码,却发现你的 tag 是 C++。不过也不影响,大同小异。
rand 函数是随机数发生函数,这个函数是有规律的(你也发现了)。
srand 是播种函数,为随机数发生器生成一个种子,然后 rand 函数根据这个初始化种子生成随机数。
至于算法,大部分随机数发生器都使用线性同余算法。
下面是C++代码:
int __cdecl rand ( void ) { _ptiddata ptd = _getptd(); return( ((ptd->_holdrand = ptd->_holdrand * 214013L + 2531011L) >> 16) & 0x7fff ); }
输出是取除最高位的高 15 位的结果(32 位整数先右移 16 位,再取低 15 位)。
15
32
16
参考: http://www.cplusplus.com/reference/random/
srand只是用来设置随机种子
http://zh.wikipedia.org/wiki/%E7%A1%AC%E4%BB%B6%E9%9A%8F%E6%9C%BA%E6%95%B0%E7%94%9F%E6%88%90%E5%99%A8
题主貌似搞错了
srand
的功能了,这个函数用来设置随机数的种子,并不是用来生成随机数的。在种子确定的情况下,不断调用rand
产生的值序列就是确定,这就是伪随机。所谓真随机,完全不可预测的随机数,一般都是要读取一些外部设备的白噪声来获得随机数,比如耳机输入口的噪声,或者网卡接口的噪声等。*nix 系统里面有个
/dev/random
就是用来产生这种真随机数的。真随机是无法通过某个固定算法来模拟的,因为一旦有了固定算法,随机序列就可以被预测,它就不算真随机了。
刚才去看了 php 的源码,却发现你的 tag 是 C++。不过也不影响,大同小异。
rand
函数是随机数发生函数,这个函数是有规律的(你也发现了)。srand
是播种函数,为随机数发生器生成一个种子,然后rand
函数根据这个初始化种子生成随机数。至于算法,大部分随机数发生器都使用线性同余算法。
下面是C++代码:
输出是取除最高位的高
15
位的结果(32
位整数先右移16
位,再取低15
位)。参考: http://www.cplusplus.com/reference/random/
srand只是用来设置随机种子
http://zh.wikipedia.org/wiki/%E7%A1%AC%E4%BB%B6%E9%9A%8F%E6%9C%BA%E6%95%B0%E7%94%9F%E6%88%90%E5%99%A8