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

时间:2018-03-05 13:35:17

标签: c random numbers

我想在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等数字......

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

3 个答案:

答案 0 :(得分:4)

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

基本上,您需要保持生成器进程正常运行,这样您就不需要重新播种它。

答案 1 :(得分: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())。

答案 2 :(得分:1)

如您所知,在同一秒内,time(NULL)会返回相同的值,因此如果您在一秒钟内多次调用您的程序,则输出将不会发生任何变化。

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

您可以采取以下措施:

  1. 使用“真正”的随机种子,也许是从/dev/random读取的种子。
  2. 将种子“混合”一点。在Unix系统上,一种流行的技术是调用srand(time(NULL) ^ getpid())
  3. 丢弃rand()
  4. 中的前几个值
  5. 使用rand()返回的值的高位,而不是低位。例如,根据C FAQ list的建议,而不是rand() % N,请使用rand() / (RAND_MAX / N + 1)