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

int main(int argc, char** argv) {


    srand(time(NULL));
    int r = rand();

    printf("%d\n", r);

    return (EXIT_SUCCESS);
}

当我在几秒钟内重复运行此代码片段时,我得到了越来越多的数字,例如 213252683、213975384、214193875、214445980。在我看来,我只是在打印出系统时间 - 这个假设似乎待我添加行时确认 printf("%d\n", time(NULL));到代码。我究竟做错了什么?我在 Mac OS X 10.6.1 (Snow Leopard) 上运行,但我只使用标准库函数,所以它不应该有所作为。谢谢!

4

5 回答 5

3

伪随机数生成为从初始种子派生的混沌序列。srand通过设置这个种子来初始化随机性。显然,序列中的第一个随机数是种子本身 - 这是time()您设置的值。

这就是为什么生成随机序列的正确方法是srand()在程序开始时只调用一次,然后只调用rand()(好吧,也许直到序列开始循环,这不应该太快发生,但是取决于生成函数)。srand()如您所见,过于频繁地调用会降低随机性。

于 2012-05-06T00:48:30.103 回答
1

如果它有帮助,我通常会这样使用它:

int rand_between(int min, int max)
{
  static int flag = 1;
  FILE *urandom;
  unsigned int seed;

  if (flag)
    {
      flag = 0;
      if (!(urandom = fopen ("/dev/urandom", "r")))
      fprintf(stderr, "Cannot open /dev/urandom!\n");
      fread(&seed, sizeof(seed), 1, urandom);
      srand(seed);
    }
  return ((int)rand() % (max - min)) + min;
}

要获得一个随机的大写字母:

char letter = (char)rand_between('A', 'Z');
于 2012-05-06T04:51:19.373 回答
0

当我在几秒钟内重复运行此代码段时,我得到的数字序列越来越多,例如 213252683、213975384、214193875、214445980。

我无法重现这一点。在我的系统(Debian Linux)上,我得到未排序的数字。此外,结果与您在 print 时得到的结果不同time(NULL)

这应该是:您正在使用当前时间(以秒为单位)为随机数生成器播种。因此,只要时间(精确到秒)相同,您的程序就会打印相同的结果。

我究竟做错了什么?

嗯,这取决于你想要什么。如果您希望每次运行都使用随机数,则需要更好的随机性来源。您可以尝试gettimeofday具有更高分辨率(通常是 ms,我相信)的函数,例如 。此外,混入其他随机来源,例如进程的 ID。

在大多数程序中,您看到的效果是没有问题的,因为通常srand()只在开始时调用,然后rand()在每次调用时返回不同的数字。

如果你想要“安全”(即不可预测的)随机数,那就是另一回事了。参见例如维基百科的概述。

于 2012-05-06T00:53:19.130 回答
0

随机数生成器差异很大,因此很难在其他机器上重现。看起来您的实现中的第一个数字只是种子值。以我为例,第一个数字似乎与种子线性相关。一般来说,你会srand在一个程序中调用一次,rand多次调用,连续调用会得到更随机的结果。如果你想避免这个问题,这样做是合理的:

srand(time(NULL));
rand();
int r = rand();

printf("%d\n", r);

第一次rand调用确保种子不会被返回,下一次调用应该选择看起来更随机的东西。请注意,如果您在足够短的时间跨度内运行该程序两次(这样time(NULL)两次运行都相同),您将获得完全相同的结果。这绝对是意料之中的——pid + time如果这是一个问题,请使用不同的种子值(可能是一个好的开始,或者只是一个更高分辨率的时间)。

于 2012-05-06T01:59:51.163 回答
0

您应该使用 random() 而不是 rand()。它在各方面都优于 rand(),它也包含在 stdlib 中。
试试下面的代码:

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

int main(int argc, char** argv) {
int r = random();
printf("%d\n", r);
return (EXIT_SUCCESS);
}
于 2013-01-22T04:06:51.603 回答