C语言中rand()函数存在问题

4

可能是重复问题:
为什么使用rand()总是得到相同的随机数序列?

这是我现有的文件:

#include <stdio.h>

int main(void) {
    int y;
    y = generateRandomNumber();
    printf("\nThe number is: %d\n", y);
    return 0;
}

int generateRandomNumber(void) {
    int x;
    x = rand();
    return x;
}

我的问题是rand()总是返回41。我在Windows上使用gcc...不确定该怎么办。
编辑:使用时间生成随机数不起作用。它给我一个数字(大约12000),每次调用时只是稍微增加一点(大约每秒+3)。这不是我需要的随机性。我该怎么办?

2
为什么使用rand()函数总是获得相同的随机数序列? - Kip
1
请查看这个问题,了解关于它只随时间改变的答案。http://stackoverflow.com/questions/1068350/random-number-function-is-misfiring 你只需要在程序开始时种子一次即可。 - GManNickG
6个回答

8

您需要为它提供一个种子。

来自互联网 -

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

int main(void)
{
  int i, stime;
  long ltime;

  /* get the current calendar time */
  ltime = time(NULL);
  stime = (unsigned) ltime/2;
  srand(stime);

  for(i=0; i<10; i++) printf("%d ", rand());

  return 0;
}

2
请注意,time(NULL)通常足够使用,但在某些情况下,您需要更多的熵来生成足够好的种子。对我来说,这总是很奇怪的,为了生成好的伪随机数(rand()的输出),您首先需要想出一个好的伪随机数(种子)。 - Graeme Perrow
2
@Graeme - 在那种情况下,你要找的词是“Catch-22”。 - Chris Lutz

8

标准技巧是:

srand(time(0));  // Initialize random number generator.

注意,函数名是 srand ,不是 rand

在你的 main 函数中只需执行一次此函数。之后,只需要调用 rand 函数即可获取数字。

根据实现方式,获取并丢弃 rand 的一些结果可能有助于使序列与种子值分离。


4

在调用 generateRandomNumber 函数之前,尝试调用 srand(time(NULL));

正如其他人所说,你需要在应用程序启动时调用一次 srand() ,而不是每次调用 rand() 时都调用它。


这样不行,因为如果我再次调用它,它会给我一个稍微增加了的数字。 - akway
3
确保你只进行一次播种(seed),而不是在每次调用rand()时都进行。 - Fred Larson
1
你只需要在随机数生成器中种植一次种子。 - 1800 INFORMATION
我的前一个评论是@akway。我的观点是在每个rand()调用之前进行srand()调用会导致随机数质量不佳。 - Fred Larson
我的也是。听起来我们都达成了一致。 - 1800 INFORMATION

4
这是因为rand()隐式地被种子值设为1。
如果你不想每次运行程序时得到相同的数字序列,应该在程序启动时使用一个从一次运行到另一次运行改变的值(使用srand())来设置种子值。
时钟时间是一个流行的选择,但要注意,这是可预测的,如果你希望数字序列是不可预测的,这可能会成为一个漏洞。

哦,我本以为初始种子会被留空(就像 C 语言中的其他东西一样),但是在 manpage 中确实有这个说明:“如果没有提供种子值,则 rand() 函数会自动使用值 1 进行初始化。” - Jason C
@Jason,使用固定种子确定序列有助于测试库。实际应用程序需要自己设置生成器的种子,并且通常需要比rand()更好的生成器。 - RBerteig

2

有时编译器使用相同的随机种子来帮助调试,这很好,但会使随机化失去意义。有一些代码示例可以使用某些数据集(通常是系统时间)来设置您的随机生成器的种子,但这就是为什么您会反复得到相同的数字的解释。


是库而不是编译器设置初始种子。而且它不是“有时”,而是“总是”。 - Jonathan Leffler

1

像以前一样,一个种子。通常是像time()或pid()这样的东西。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接