C/C++中随机数的获取: 伪随机函数

1. C库中的伪随机函数rand的实现

《The GNU C Library》里说的,大概如下:

公式: Y=(a*X+c)mod m

其中,a,c,m都是常数

一种取值是:

a = 0x5DEECE66D = 25214903917

c = 0xb = 11

    m = 2^48

用上面的公式可以这样写:

__int64 rand ()
{
static __int64 r = 0;
const __int64 a = 25214903917;
const __int64 c = 11;
const __int64 m = 1 << 48;
r = (r * a + c) % m;
return r;
}

2. ASNI 随机数生成的理解
ANSI中和随机数生成相关的函数是rand()和srand()。
rand()函数的原理:y=(a*x+b)mod n
ANSI通过记录最近生成的数来产生伪随机数。每次调用rand时,它取最近生成的一个数,对这个数执行一系列的操作,产生下一个数。
所以,在程序中如果多次调用rand的话,会生成不同的随机数。
但是,如果你多次运行同一个程序的话,产生的随机数序列是一样的,为什么会这样呢?主要是rand在设计的时候需要一个种子,这个种子作为整个随机数过程的起始值。开始运行程序时这个值是库里给定的,所以每次运行程序产生的随机数序列是一样的。
如果想产生不同的序列的话,就需要改变初始种子。使用srand函数用来设定种子。
可以利用每次运行程序时的时间来作为种子。这样就会产生不同的序列。

3. 随机数计算的相关

关于time_t time(0)
    time_t 被定义为长整型,它将返回从1970年1月1日零时零分零秒到现在所经历过的时间,单位为秒。比如输出 cout<<time(0) ,将得到值约为1169174701,约等于37(年)* 365(天)* 24(小时)* 3600(秒)(月和日不计)。
关于ran_num=rand()%6
    将rand()的返回值与6求模是必须的,这样才能确保目的随机数落在[0,6)之间,否则很可能会得到一个非常巨大的数值 (RAND_MAX一般为32767)。一个通用的公式是:要想取得[a,b)之间的随机整数,使用(rand()%(b-a))+ a,结果包含 a 而不含 b 。

4.随机函数 rand,srand,random,srandom 的区别与使用
使用方法 :
假如你想产生 1-10 之间的一个随机数, 你应该像下面这样编码

  j = 1 + (int) (10.0 * (rand() / (RAND_MAX + 1.0)));

 而不是下面这样的代码

   j = 1 + (rand() % 10);


结论:如果你使用 srandom 种植种子, 则你应该使用 random 返回随机数, 如果你使用 srand 种植种子, 则你应该使用rand返回随机数。
不过srand和rand官方已经不推荐使用。原因是产生随机数的性能不是很好, 另外是随机数的随机性没有random好, 再者就是不是线程安全。

posted @ 2012-08-25 20:29  Mr.Rico  阅读(2340)  评论(0编辑  收藏  举报