C/C++中生成随机序列——随机函数的选择和自我实现

来源:互联网 发布:mac将文件夹移动硬盘 编辑:程序博客网 时间:2024/06/05 21:54

一、缘由

最近需要将windows下的项目移植到linux下,但因为项目使用到随机函数,导致最后两边的结果有些微差异,无法判断是否移植成功。因此需要将两边随机函数统一。
大家常用的随机函数有srand()/rand();

二、srand()/rand()

1.项目中采用的随机数生成函数是 rand()。
rand()返回一随机,数值的范围在0至RAND_MAX 间。

它的内部实现是用线性同余法做的,产生的新随机数作为下一次随机数的种子,它不是真的随机数,因其周期特别长,故在一定的范围里可看成是随机的。
线性同余法的原理:
X_{n+1} = ( a * X_n + c ) mod m

windows 下RAND_MAX 为32767(16位)。
linux下为2147483647(32位)
如果不用srand()指定随机函数,指定默认情况下种子为1。

2.其用法为:
void srand(unsigned int seed);
int rand();

#include <stdlib.h>//rand()头文件#include <time.h> //为了srand((unsigned)time(NULL));//采用系统当前时钟作为种子int num_rand = rand();

3.c库的rand()的实现代码为(windows下):

void __cdecl srand (unsigned int seed){    #ifdef _MT        _getptd()->_holdrand = (unsigned long)seed;    #else /* _MT */        holdrand = (long)seed;    #endif /* _MT */}int __cdecl rand (void){   #ifdef _MT    _ptiddata ptd = _getptd();    return( ((ptd->_holdrand = ptd->_holdrand * 214013L + 2531011L) >> 16) &    0x7fff );   #else /* _MT */    return(((holdrand = holdrand * 214013L + 2531011L) >> 16) & 0x7fff);   #endif /* _MT */}

默认种子是1;
/* Return a random integer between 0 and RAND_MAX. */
int
rand (void)
{
return (int) __random ();
}

三、自己实现的rand()

myrand.h:

namespace randomspace{    static int state =1;    void srand(int seed);    int rand();}

myrand.cpp

#include "myrandom.h"void randomspace::srand(int seed) {    state = seed;}int randomspace::rand() {    return(((state = state * 214013L + 2531011L) >> 16) & 0x7fff);}

多次运行,结果均与windows下rand()函数一模一样:
这里写图片描述

0 0