前一段做项目的时候,使用了rand()函数产生了1024*150个随机数,当时并没有了解rand()的用法, 突然间发现每次的结果都一样,才自己去看了一下这个函数的机制.
rand()函数介绍
rand()是std标准库中的声明的函数,包含在c++头文件< stdlib >中, 其本质是一个伪随机数生成器(pseudorandom number generator), 其本质是采用线性同余法( linear congruential method),根据一个给定的seed值来产生相应的随机数.
关于seed值
seed值决定了rand()产生的随机数序列, 我们可以在调用rand()函数之前先调用srand()函数来对seed值进行设置,如果不设置,seed的缺省值是1,注意srand()一定需要在循环之前进行调用, 例子如下:
srand(10);
for(int i = 0 ; i < 100 ; i++)
{
int ret = rand();
}
每次设置seed之后,rand()产生的序列都会从你设置的值开始刷新,因此如果在循环中设置seed, 每次rand()产生的值都会一样.
for(int i = 0 ; i < 100 ; i++)
{
srand(10);
int ret = rand(); // 每个循环ret的值都会相同
}
如果我们想要真正的随机值,可以通过srand(time(0))
来设置随机seed值.
关于rand()在不同平台的使用
我们可以通过设定seed值来改变rand()产生的随机数, 当seed值固定之后,产生的连续随机数的值也就固定下来, 在这里还有一个小tips, 线性同余法并不需要有seed值一个参数,只是其余的参数我们无法进行设定, 在不同的编译器下,其余参数的缺省值是不同的,因此在不同平台运行rand(),会得到不同的随机数,我自己试过在linux平台上使用gcc和window平台使用vs2015进行运行,得到的结果完全不同,针对不同编译器的缺省值设定,大家可以参考维基百科上的描述: 线性同余发生器
解决不同平台随机值不同的方法
在有的项目里,我们希望保证在所有平台下,产生的随机序列值都是一样的,那么可以采用C++11中加入的新的随机发生器,比如std::mersenne_twister_engine(梅森旋转法), 新的发生器的功能更加强大,可以产生不同概率分布的随机数.
下面给一个例子,在gcc和vc编译器下产生的结果都一样.
std::mt19937 generator(1);
for(int i = 0 ; i < 100 ; i++)
{
int ret = generator();
}
好了就到这里.