文档库 最新最全的文档下载
当前位置:文档库 › Linux下的伪随机数生成函数

Linux下的伪随机数生成函数

在 Linux的 GCC 中,涉及到伪随机数生成器的函数声明位于 stdlib.h

rand系列——
int rand(void);
int rand_r(unsigned int *seedp);
void srand(unsigned int seed);
遵从标准SVID 3
BSD 4.3
ISO 9899
POSIX 1003.1-2003.
其中的 ISO 9899标准也就是 C语言的ISO标准系列号


random系列——
long int random(void);
void srandom(unsigned int seed);
char *initstate(unsigned int seed, char *state, size_t n);
char *setstate(char *state);
仅遵从标准BSD 4.3


可见 random系列函数不是C语言的原生标准,属于BSD、GCC的扩展。
该扩展的最大目的是为了提供一种循环周期超长的伪随机数生成函数,因为
rand系列函数通常采用“乘同余”算法,循环周期小于 2**31 量级——尽管
其int型返回值均匀分布于 0 ~ 2**31-1 之间。而random系列函数使用了
“非线性增长-反馈”算法,实现了大约 16* (2**31) 量级的长周期。

当然,GCC的 rand函数也非(像 Visual C++那样)采用简单的乘同余算法,
而是“非线性增长-反馈”算法,其实就是 random函数!不过为了可移植性,
避免在其它平台上误用简单的rand函数而遇上麻烦,推荐使用 random函数!
★ ~~~~~~~~~~~~~~~~~~~~~~


++参考++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Excel绘制的散点图 rand.gif、random.gif,用连续伪随机数序列
按照 (a,b)、(c,d)、(e,f)、……方式确定二维正方区域中3000个点的坐标,
可见无论是 GCC-rand 还是 GCC-random 绘制出的散点图都未见自相关特征。



++对比+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

所谓“非线性增长-反馈”算法,类似我曾经在《随机数及其生成器》
一文中给出的伪代码—— 乘同余法之所以循环周期短,是因为其每一步循环后
都只有一个变常数 next 被送往下一循环,即使是unsigned long next也不过
64位;而非线性算法使用的是 一组 变常数在循环间传递,可以高达2048位,
最低要求64位(同线性方法)。“有限状态自动机”的状态数目大大增加,
也就不容易发生循环。

不过,“非线性增长-反馈”算法的速度慢一些,但是超长周期的特点
使其可以连续生成伪随机数而不必频繁初始化;较快的线性方法因为要定期作
时间代价高昂的初始化操作,不便于快速产生超长串数据。另外,为了避免
自相关缺陷,需要使用一些技巧才能生成二维或者更高维随机点的坐标。
线性同余法还有一重要缺陷:低位数据 的随机性比 高位数据 差。


网上曾有人说 Visual C++ 的随机数生成器性能高于 GCC,那是因为
VC++ 用的是不可靠的简单“线性同余算法”,没有参考价值。

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++






=============================使用方法提要=============================

rand()、random() 返回的伪随机数都均匀分布在 0 ~ RAND_MAX 之间,
其中 RAND_MAX 是在头文件中定义的符号常量,通常就是signed int
数据类型的上限。


首先要调用系统时间初始化: #include
srand( (unsigned)time(NULL) );
或者 srandom( (unsigned)time(NULL) );

以下省略 random系列函数


尽可能使用随机数的高字节部分——
就是说不要用“%”而用“/”运算:j= RANGE* rand() / (RAND_MAX+1.0) ;

这样将随机数范围从 [0, RAND_MAX] 也就是 [0, RAND_MAX+1.0)
缩放到 [0, RANGE) ,其中 RANGE 需要定义为浮点数,防止整型运算!





rand_r 函数用于在多线程程序中为每一个线程维护一个独立的伪随机数序列,
不过其传递的种子仅为 unsigned int型,有限状态数太少。更好的线程安全的
伪随机数生成器是 drand48_r ,48位的种子传递。

相关文档