关于C++中的随机数
发布网友
发布时间:2022-04-30 01:58
我来回答
共5个回答
热心网友
时间:2022-06-28 14:53
多数编译器提供实现随机数发生器的库函数,但是不幸的是,并不是每个库函数都一样。
但是我们可以自己定义一个随机数类来实现随机数,下面我们先分析一下过程。
首先我们要确定有下面变量:
unsigned long randSeed;随机数的种子
还有与种子操作产生随机数的相关数据:
const unsigned long maxshort=65536L;
const unsigned long multiplier=1194122693L;
const unsigned long adder=12345L;
上面的这些数据都可以自己更改,到后面再具体来介绍为什么这么设定这些数据作为相关数据。
第二步:我们确定相关函数
种子生成器(即构造函数):
RandomNumber(unsigned long s);
随机整数发生器:
unsigned short Random(unsigned long n);
浮点数发生器:
double fRandom(void);
确定了这些,我们可以声明随机数类了:
#include
//用当前种子产生随机数
const unsigned long maxshort=65536L;
const unsigned long multiplier=1194211693L;
const unsigned long adder=12345L;
class RandomNumber
{
private:
//存放种子的私有成员
unsigned long randSeed;
public:
//构造函数 。缺省值0表示系统自动给出种子
RandomNumber(unsigned long s=0);
//产生0<=value中,用参数0调用时,
它反回一个无符号长整数(32位),表示从基准时间(1970.1.1.午夜或者1904.1.1午夜)至今已经过去的秒数。
任何情况下产生的数都是巨大的无符号型长整数.基于两者的选择,我们很理所当然地用一个选择语句来描述:
RandomNumber::RandomNumber(unsigned long s)
{
if(s==0)
randSeed=time(0);//系统时间作种子
else
randSeed=s; //用户提供种子
}
上面的就是种子生成器的代码。
到这,我们得到了种子。这只是没有加工的种子,其实每次迭代,都是用常量来产生新的无符号的种子:
randSeed=multiplier*randSeed+adder;
通过上面的表达式,我们得到了更新后的种子,这就是我们在下面的用到的原理,通过更新新种子,再将其
右移16位(不知道各位是否发现一直到现在我们得到的都是32位的种子),这时得到的结果就是在0至65535的随机数
,不急,我们再用除法把这个数映射到0……n-1。这就是Random(n)的结果,看下面代码:
unsigned short RandomNumber::Random(unsigned long n)
{
randSeed=multiplier*randSeed+adder;
return (unsigned short)((randSeed>>16)%n);
}
这里就得到随机整数了。
怎么得到随机浮点数呢?我们通过随机整数来实现:
首先调用整数Random(maxshort),大家都知道他的范围了吧,再用double(maxshort)除,这样就得到了0<=fRandom()<=1.0
的实数随机数:
double RandomNumber::fRandom(void)
{
return Random(maxshort)/double(maxshort);
}
至此,完成
下面一步是怎么写成头文件:
先把以上代码按顺序写放在一起,编不编成库存文件就随各位了,我是不会编的,直接放头文件也一样。
然后在开头加上:
#ifndef RANDOMNUMBER_INCLUDE
#define RANDOMNUMBER_INCLUDE
未尾加上:
#endif就行了
然后保存为random.h就可以了,至于扩展大家自己看吧,
热心网友
时间:2022-06-28 14:53
主要是rand每次取的随机种子都是一样的!!!
利用srand((unsigned)time(NULL)) 可以将系统时间当作随机种子
因为他取的是系统时间 而时间又是在不断变化的!!!
固在调用rand()便可以得到不同的随机数!
用法:
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
void main()
{
int nI = 0;
int nJ = 100;//随机数的最大值
int nCont = 0;//控制随机数的个数
srand(time(NULL)); //取系统时间为随机种子
while(1)
{
nI = rand()%nJ; //取随机数
printf("%d\n",nI);
nCont++;
if(nCont == 10)//取出10个随机数后程序结束
{
break;
}
}
}
热心网友
时间:2022-06-28 14:54
当初我从其他语言转向C\C++的时候也有这种想法
我当时还写了一些看上去更"顺眼"的替代函数
但是由于年代久远早已失传
今天为了LZ,只好回忆一番,兼凭吊往事
示例代码如下
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
void Randomize()
{
srand((unsigned)time(NULL));
}
float Rnd()
{
return (float)rand() / (float)RAND_MAX;
}
int main()
{
Randomize();
for(int i = 0; i < 100; i++)
printf("%f\n", Rnd());
return 0;
}
这样无论是使用格式,还是函数返回类型都比较符合VB的规则了
注意头文件要加上
热心网友
时间:2022-06-28 14:55
#include <time.h>
int main()
{
srand( (unsigned)time( NULL ) );
int a = 0;
for ( int i = 0; i < 10; i++ )
{
a = rand();
}
}
以时间为随机数种子
热心网友
时间:2022-06-28 14:55
好像没有更好的了。
srand和rand挺好用的啊。