标准库rand()函数的缺陷以及Blitz++随机数生成的简介
(newsuppy, 转载请注明出处)
http://blog.csdn.net/newsuppy/archive/2004/09/15/104848.aspx
当我们需要在某个任务中使用随机数,通常我们习惯于使用标准库的rand函数。像这样:srand(time(0)); // 时间种子
rand() % MAX_RAND;
标准库的rand函数使用线性同余算法,是生成速度相当快的一种随机数生成算法。在多数情况下也确实能满足我们的要求,但是对于一些特殊目的应用这个算法生成的随机数是不行的,比如某些加密算法,蒙特卡罗积分等(在.NET中创建随机密码的加密安全随机数就不能使用Random类的线性同余随机数,而要使用System.Security.Cryptography命名空间中的相关随机数生成类)。
这个线性同余算法的实现可以在很多书籍中找到。下面我给出一个The C Programming Langurage 2nd中的一个实现,这也是普遍使用的标准库随机数算法的实现:
|
unsigned long int next = 1; /* rand: return pseudo-random integer on 0..32767 */ int rand(void) { next = next * 1103515245 + 12345; return (unsigned int)(next/65536) % 32768; } /* srand: set seed for rand() */ void srand(unsigned int seed) { next = seed; } |
这个实现的问题在于rand函数return行中的那个32768,在标准库中这个数字定义为RAND_MAX宏,在VisualC++和Mingw32编译器的stdlib.h头文件(或者cstdlib)中你都可以发现RAND_MAX的值为32768。也就是说这个算法的随机数分布在0--RAND_MAX中,而在一般编译器中就是0--32768。假设你的算法需要的是300000多个的随机数,那么使用rand函数会产生重负次数近30次的随机数!