C随机数发生器 - 它变化得那么慢。该怎么办?

问题描述 投票:0回答:3

我想在1-10000之间创建一个数字。

#include <stdio.h>
#include <stdlib.h>

int main() {

    int numb;
    srand(time(NULL));

    numb = (rand()%9999)+1;

    printf("%d", numb);

}

但由于某种原因,它产生的数字如此缓慢。我的意思是,让我说我运行程序。它在一秒钟之后给了我一个“1145”,我再次跑了它并且它说“1151”... 5秒之后,它说“1211”

正如你所看到的,它们非常接近数字。我希望它变化如此之快。如果我在5秒内使用它5次,我想要像49,1124,6665,9000,140等数字......

我该怎么做才能实现这一目标?对不起英语,并提前感谢...

c random numbers
3个回答
4
投票

C随机数发生器不是设计用于重复播种,并且播种到时钟时间可能会产生相同的序列,最后一秒左右。

基本上,您需要保持生成器进程正常运行,因此您无需重新播种它。


1
投票

如果您的程序每秒运行的次数超过一次,则需要使用系统时钟以外的其他方式为随机数生成器播种。例如,您可以从/dev/urandom获取几个字节,如下所示:

#include <stdio.h>
#include <stdlib.h>

int main() {
    int s, numb;
    FILE *f;

    f = fopen("/dev/urandom", "rb");
    fread(&s, sizeof(int), 1, f);
    fclose(f);
    srand(s);

    numb = rand() % 9999 + 1;
    printf("%d\n", numb);
    return 0;
}

但请记住,rand()的许多实现很容易根据几个连续的输出值进行预测。有更好的替代品(例如,arc4random())。


1
投票

如您所知,在同一秒内,time(NULL)返回相同的值,因此如果您在一秒钟内多次调用您的程序,您的输出将根本不会更改。

如果你一次调用你的程序,然后一秒钟再调用一次,time(NULL)的输出将增加一。现在,你可能希望你交给srand()的值的任何差异都会在下一次调用rand()的返回值中产生任意大的差异。事实上,我也希望这一点,但就在最近我的一个系统(我忘了哪个),我很失望地发现事实并非如此。传递给srand()的值的微小变化在rand()返回的下一个值中产生了小值。

你可以做几件事:

  1. 使用“真正的”随机种子,也许从/dev/random读取。
  2. 将种子“混合”一点。在Unix系统上,一种流行的技术是调用srand(time(NULL) ^ getpid())
  3. 扔掉rand()的前几个值。
  4. 使用rand()返回的值的高位,而不是低位。例如,正如C FAQ list所建议的那样,使用rand() % N而不是rand() / (RAND_MAX / N + 1)
© www.soinside.com 2019 - 2024. All rights reserved.