C++产生随机数的程序

r=2053.0*r+13849.0;s=(int)(r/65536.0);r=r-s*65536.0;rnd=r/65536.0;//rnd能产生0~1之间的随机数这段... r = 2053.0 * r + 13849.0;
s = (int)(r / 65536.0);
r = r - s * 65536.0;
rnd = r / 65536.0;
//rnd能产生0~1之间的随机数

这段程序看不懂啊,为什么这样就能产生随机数呢?
展开
 我来答
wangbwell
2011-03-02 · TA获得超过1238个赞
知道小有建树答主
回答量:490
采纳率:0%
帮助的人:729万
展开全部
r = 2053.0 * r + 13849.0; //这是两个有个是素数吧 应该是的 2053就是
//质因数分解13849=11*1259
//那么这两个素数的公倍数大于65535吧
//而65535是unsigned short两个字节吧
//这样递归 乘开后就能分散到(低2字节)所有0-65536的数字

这个随机产生办法的灵魂就在这句了:r = 2053.0 * r + 13849.0

其实就是《线性同余法》 产生的随机数
线性同余法:一般递推公式为:Xn = (a*X(n-1) + c)%M Rn = Xn/M
其中M为模数,a为常子(乘数),c为增量(加数),且均为非负整数.

给定一组参数,就可以得到一列数,它是否具有类似于均匀随机变量的独立抽样序列的性质,与这些参数的选择有关.例如,用下面的递推公式产生的随机数就是比较好的随机数:
a=235 c=0 M=0xFFF-21 种子x0小于M就行

s = (int)(r / 65536.0); //取整 得到高字(高2字节)部分的整数
r = r - s * 65536.0; //去掉高字(高2字节)部分的整数 不细讲 分解就知道 明显
其实你会发现 上面3句后 s和r仍然为整数 下面假定r, s是unsigned int了

改写上面两句,就容易理解了:(去掉乘除法, 速度还能快一点)
r = r & 0xFFFF; //(一个语句解决,看明白了吧) r的值在0-65536之间

rnd = r / 65536.0; //65536.0使除法不进行整数除法 rnd是0和1之间 由上面一看就知道了

程序好一点的写法:

float MyRand(unsigned int seed=1)
{
static unsigned int _seed = seed& 0xFFFF; //第一次初始化种子
_seed = (2053 * _seed + 13849) & 0xFFFF;
return (float)_seed / (float)(0xFFFF);
}

就这样吧
柯墨
2011-03-02 · TA获得超过215个赞
知道小有建树答主
回答量:120
采纳率:0%
帮助的人:68.1万
展开全部
要看r的来源了吧。。。如果r的来源是某个和时间有关的数 就可以解释了
后三句就是 让某个在65536和0之间的数除以65536获得0和1之间的随机数
更多追问追答
追问
不好意思,忘了写
double r = 1.0;
那第一句是干嘛呢?
2053.0和13849.0这两个数有什么特殊的呢?
追答
r应该是函数外面进来的吧 不是全局变量也得是个指针变量 前一个得出的随机数是后一个随机数的r
然后那两个值貌似是随便找的 为了扩大r的值
本回答被提问者采纳
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式