C++ rand()不给我一个随机数(即使使用了srand())
好吧,我开始失去理智了。我所要做的就是随机选择一个介于0和410之间的数字,根据page,我的代码应该可以做到这一点。因为我想要一个随机数,而不是伪随机数,所以我也在使用srand(),就像thread告诉我的那样。但这不起作用。我得到的只是一个数字,这个数字取决于我上次执行死刑的时间。例如,如果我以最快的速度再次执行,则数字通常比最后一个数字高6个数字,如果我等待的时间更长,则数字会更高,等等。当它达到410时,它会返回到0并重新开始。我错过了什么 编辑:噢,如果我删除C++ rand()不给我一个随机数(即使使用了srand()),c++,random,srand,C++,Random,Srand,好吧,我开始失去理智了。我所要做的就是随机选择一个介于0和410之间的数字,根据page,我的代码应该可以做到这一点。因为我想要一个随机数,而不是伪随机数,所以我也在使用srand(),就像thread告诉我的那样。但这不起作用。我得到的只是一个数字,这个数字取决于我上次执行死刑的时间。例如,如果我以最快的速度再次执行,则数字通常比最后一个数字高6个数字,如果我等待的时间更长,则数字会更高,等等。当它达到410时,它会返回到0并重新开始。我错过了什么 编辑:噢,如果我删除srand(time(N
srand(time(NULL))代码>行我每次运行程序都会得到相同的数字(41)。这甚至不是伪随机的,这只是一个静态数字。只要从中复制第一行代码,我仍然一直是41号。我是《23号》续集中的明星,还是我错过了什么
int main(void) {
srand(time(NULL));
int number = rand() % 410;
std::cout << number << std::endl;
system("pause");
}
int main(无效){
srand(时间(空));
整数=兰德()%410;
std::cout尝试通过时间(0)更改时间(NULL)(这将为您提供当前系统时间)。如果它不工作,您可以尝试通过执行时间(0)*1000将时间(0)转换为毫秒。来自手动:
time()将时间返回为自历元以来的秒数,
1970-01-01 00:00:00+0000(UTC)
这意味着,如果您在同一秒启动两次程序,您将使用相同的值初始化srand,并将获得相同的PRNG状态
如果您通过调用srand
删除初始化,您将始终从rand
中获得完全相同的数字序列,恐怕您无法获得真正的随机数。内置函数只提供伪随机数。此外,使用srand和rand,因为前者使用的方法与后者相同e第二个。如果你想制作真正的随机数,你必须找到一个正确的熵源,例如使用大气噪声,就像www.random.org的方法一样
这里的问题在于随机性算法所使用的种子:如果它是机器提供的一个数字,它就不可能是不可预测的。通常的解决方案是使用外部硬件。这就是使用不推荐的随机数生成所得到的结果
rand
生成一个固定的数字序列(这本身就很好),而且做得非常非常糟糕
您可以通过srand
告诉rand
在序列中的起始位置。由于您的“起始点”(称为种子btw)取决于自1970年1月1日0:00:00 UTC以来的秒数,因此您的输出明显取决于时间
正确的方法是使用C++11库。在您的具体示例中,这看起来有点像:
std::mt19937 rng (std::random_device{}());
std::uniform_int_distribution<> dist (0, 409);
auto random_number = dist(rng);
std::mt19937 rng(std::random_device{}());
标准:均匀分布区(0409);
自动随机数=距离(rng);
有关rand
的弊病和
的优点的更多信息,请查看
最后一句话,像我在上面所做的那样,播种std::mt19937
不是很理想,因为MT的状态空间比单个调用std::random_device{}()得到的32位要大得多
。这不是玩具程序和标准学校作业的问题,但仅供参考:这是我对MT的整个状态空间的看法,以及答案中的一些有用建议。不幸的是,没有特定硬件(通常太慢而不实用)的计算机无法获得真正的随机数
因此,您需要使用一个伪生成器,但是您需要小心地使用它们
函数rand
用于返回介于0和rand_MAX之间的数字,从广义上讲,它满足均匀分布的统计特性。您最多可以期望绘制的数字的平均值为0.5*rand_MAX
,方差为rand_MAX*rand_MAX/12
通常情况下,rand
的实现是一个线性同余生成器,这基本上意味着返回的数字是前一个数字的函数。这可以产生出人意料的好结果,并允许您使用函数srand
为生成器种子
但是重复使用srand
会破坏生成器的统计特性,这就是发生在您身上的情况:您对srand
的使用与系统时钟时间相关。您观察到的行为完全是意料之中的
你应该做的是只调用一次srand
,然后使用rand
绘制一个数字序列。按照你设置的方式,你不可能轻松做到这一点。但是还有其他选择;你可以切换到一个随机数生成器(比如mersenne twister),它允许你绘制(n)您可以将n的值作为命令行参数传递
最后一句话,我要避免在绘制数字时使用模。如果模不是RAND_MAX的倍数,这将产生统计偏差。想要一个随机数而不是伪随机数
-nope sr,并且只保证返回一个不同的数。但序列仍然是伪随机的。请参阅:——具体来说,您的确切问题将在3:30分钟讨论。您所说的“随机数而非伪随机数”是什么意思?如果您只是想要一个与种子不明显相关的数字,请调用rand()
在使用某个值之前,先执行一次或多次;听起来你的rand
实现相当糟糕,它返回种子作为第一个值。如果你真的需要一个“真”随机数,那么你不能仅从软件中获得它。你可以给出它,但前提是