【问题标题】:Function srand in C++C++ 中的函数 srand
【发布时间】:2010-07-21 07:48:10
【问题描述】:

这段代码

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

int main ()
{
    printf ("First number: %d\n", rand() % 100);
    srand ( time(NULL) );
    printf ("Random number: %d\n", rand() % 100);
    srand ( 1 );
    printf ("Again the first number: %d\n", rand() %100);

    return 0;
}

有以下输出:

First number: 41
Random number: 13
Again the first number: 41

还有如下规则:

使用相同种子的两个不同初始化,指示伪随机生成器在两种情况下为后续调用 rand 生成相同的连续结果。

我明白这些话,但我不明白方法本身。为什么它又返回了 41?它是随机的还是必须根据此代码在每种情况下都返回相同的结果?

【问题讨论】:

  • 这使得调试更容易。如果您正常运行,请使用 srant(time(NULL))。如果您的程序中存在错误,请不要调用 srand() 或调用 srand(1),您将通过调用 rand() 获得相同的数字序列。请注意,每次调用 rand 都会生成序列中的下一个数字,但序列始终相同。注意 2:您应该只在应用程序中调用 srand() 一次。
  • @Martin York:好点子。从调试的角度从来没有想过这个。有道理。

标签: c++ random


【解决方案1】:

如果您在没有先调用 srand() 的情况下调用 rand(),则行为就像您使用 1 作为参数调用 srand()

此行为在原始 C 标准中定义。我手头没有完整的副本,但 The Open Group 的 POSIX 标准是次佳,因为它们包含了完整的 C 标准(带有一些扩展):

http://www.opengroup.org/onlinepubs/000095399/functions/rand.html

srand() 函数使用参数作为新的伪随机数序列的种子,这些伪随机数将由后续调用 rand() 返回。如果随后使用相同的种子值调用 srand(),则应重复伪随机数序列。如果在调用 srand() 之前调用了 rand(),则应生成与第一次调用 srand() 时相同的序列,种子值为 1。

对任何给定种子的rand() 调用的实际结果是实现定义的,除了对于任何种子x,调用nrand()生成器的种子必须返回相同的结果。因此,在您的实现中,在调用srand(1) 之后,您将始终在第一个rand() 调用中获得41,并且对于第二个rand() 调用,您将始终获得相同的结果(无论是什么),其他实现可能使用不同的产生不同结果的算法。

【讨论】:

    【解决方案2】:

    对于randsrand,C++ 标准遵循 C 标准(参见 C++0x 的第 26.8 节):

    rand 函数具有 C 标准中指定的语义,但实现可能指定特定库函数可以调用 rand

    C 标准(C99 的 7.20.2.2)非常明确地声明:

    如果在对srand 进行任何调用之前调用rand,则应生成与第一次调用srand 时相同的序列,种子值为1。

    所以第一次调用 rand 时,种子是 1。第三次调用它也是 1,这就是为什么你得到相同的值。

    您第二次调用rand 时,种子已根据当前时间设置,这就是您得到不同结果的原因。除非您确实想要相同的序列(例如在测试中),否则重新播种随机数生成器通常不是一个好主意。

    【讨论】:

      【解决方案3】:

      我觉得这个可能有问题:

      如果种子设置为 1,则生成器将重新初始化为其初始值,并生成与调用 rand 或 srand 之前相同的值。

      srand reference

      【讨论】:

        【解决方案4】:

        使用1 的值调用srand 会将生成器重置为程序启动时的初始状态。

        【讨论】:

          【解决方案5】:

          srand(3) 让您从随机数生成器中获得可重复的输出。这样,您可以编写依赖于随机数的程序,但确定性地测试它们。 (通常通过一个命令行选项调用 srand() 并提供参数,因此它可以使用 1、2、3、4、5... 作为输入运行一百次。)

          所以这符合预期。

          【讨论】:

            【解决方案6】:

            这可能是因为在您对 rand 的初始调用中,随机数生成器尚未播种,因此它使用默认值 1 来播种。

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2019-03-21
              • 1970-01-01
              • 2018-03-22
              • 1970-01-01
              • 2017-07-06
              相关资源
              最近更新 更多