我很抱歉,如果这是怎样的一个愚蠢的问题,但我是新来的C++和真的不能找到答案;
当我使用时rand(),我当然必须首先使用srand().
起初我只是导入<ctime>和做srand(time()),这有效.但如果我rand()不止一次打电话- 经常time()发生变化 - 那么我会得到同样的答案.所以例如;
#include <iostream>
#include <ctime>
#include <cstdlib>
using namespace std;
int main()
{
bool x = true;
while(x == true)
{
int num = 1;
srand(time(NULL));
num = rand();
cout<<num%10<<endl;
}
}
Run Code Online (Sandbox Code Playgroud)
可能会产生类似的东西,如6666666666777777777700000000003333333333
哪个对我的目的没有好处 - 我更喜欢像163509284749301935766这样的东西.
您应该只为随机数生成器播种一次.现在你正在循环中播种它并且time(NULL)只是意味着种子每秒更改一次,这会给你所描述的糟糕输出.
请改为:
int main()
{
bool x = true;
int num = 1;
srand(time(NULL));
while(x == true)
{
num = rand();
cout<<num%10<<endl;
}
}
Run Code Online (Sandbox Code Playgroud)
如果你真的关心产生的随机数,你可能想要使用其他东西rand().原因是rand()伪随机数生成的统计特性较差,它通常被实现为线性同余生成器.如果您需要高质量的随机性,那么您应该更喜欢其他内容,例如新的c ++随机数生成器http://en.cppreference.com/w/cpp/numeric/random.实际上甚至有一篇关于贬值旧的报告rand(),试图推动人们使用更新的c ++标准库随机函数.
在这种特殊情况下,你采用一个模数会导致一些微妙的问题:
num = rand();
cout<<num%10<<endl;
Run Code Online (Sandbox Code Playgroud)
即使rand()是完美的,如果这里的模数不返回的最大值的约数rand(),你会得到一个非均匀分布的结果.这是一个快速解释,比如说rand()[0,25]范围内的返回值,然后取模数将执行以下操作.
before after modulus
[0-9] [0-9]
[10-19] [0-9]
[20-25] [0-5]
Run Code Online (Sandbox Code Playgroud)
你会发现你更有可能得到[0-5]而不是[6-9],这意味着你现在不再生成统一的数字了.请注意,这个小范围仅用于教育目的,rand()标准规定的最大值至少为32767.但是它说明了一个重点,最大生成数越大越好.
除了模数之外,这种分布问题的均匀性具有特别隐蔽的效果,即使对于某些实施方式甚至进一步降低伪随机性的质量.
使用std::uniform_int_distribution避免了许多问题,因此我建议您更改现有代码以使用新库.这样做会是这样的:
#include <iostream>
#include <random>
using namespace std;
int main()
{
std::default_random_engine generator;
generator.seed( /* your seed for the RNG goes here */ );
std::uniform_int_distribution<int> distribution(0,9);//note the min and max parameters are inclusive here
while(true)
{
cout << distribution(generator) << endl;
}
}
Run Code Online (Sandbox Code Playgroud)