srand(1)和srand(0)之间有什么区别

时间:2011-11-08 11:16:40

标签: c++ c random srand

我刚刚发现srand(1)在调用srand之前将{C(+)的PRNG重置为状态的困难方式(如reference中所定义)。 但是,种子0似乎做同样的事情,或者在调用srand之前的状态似乎使用种子0。 这两个电话有什么不同,或者他们做同样事情的原因是什么?

例如此代码(execute on Ideone

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

int main() {
    for (int seed = 0; seed < 4; seed++ ) {
        printf( "Seed %d:", seed);
        srand( seed );
        for(int i = 0; i < 5; i++ )
            printf( "    %10d", rand() );
        printf( "\n");
    }
    return 0;
}

返回

Seed 0:    1804289383     846930886    1681692777    1714636915    1957747793
Seed 1:    1804289383     846930886    1681692777    1714636915    1957747793
Seed 2:    1505335290    1738766719     190686788     260874575     747983061
Seed 3:    1205554746     483147985     844158168     953350440     612121425

7 个答案:

答案 0 :(得分:18)

glibc是如何做到的:

  

around line 181 of glibc/stdlib/random_r.c,内部函数__srandom_r

  /* We must make sure the seed is not 0.  Take arbitrarily 1 in this case.  */
  if (seed == 0)
    seed = 1;

但这就是glibc如何做到的。这取决于C标准库的实现。

答案 1 :(得分:12)

这可能是一个实施细节。标准要求随机种子1是特殊的,并且您的特定随机生成器算法的内部寄存器可能是零初始化的,因此导致种子(0)和种子(1)的相同随机序列。我甚至打赌你的srand()实现的第一行看起来像:

if ( seed == 1 ) seed = 0;

强制符合标准的行为。

通常,rand()和srand()的随机数生成器不需要为不同的种子提供不同的序列,但是对于相同的种子使用相同的序列。所以,不依赖于产生不同随机序列的不同种子,你应该没问题。如果没有,欢迎特定于实现的乐趣。

答案 2 :(得分:7)

C和C ++标准都没有对rand()srand()的实施细节作出太多说明。细节几乎完全取决于实现者。 C标准要求:

  

如果然后使用相同的种子值调用srand,则应重复伪随机数序列。如果在对srand进行任何调用之前调用rand,则应该生成相同的序列,就像第一次使用种子值1调用srand时一样。

但它不包含不同种子必须产生不同序列的任何要求。显然,在你的系统上,零和一的种子具有相同的效果。我猜这是为了向某些软件提供向后兼容性,这些软件希望srand(0)将PRNG重置为初始状态。

答案 3 :(得分:1)

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

答案 4 :(得分:0)

当阅读手册页时,它们都声明“如果没有提供种子值,则rand()函数会自动播种,值为1”。这可能是您链接到状态的参考页面,其中播种1会重置状态。

对于0和1播种同样的结果很可能取决于实现,并且不应计算在所有平台上发生。

答案 5 :(得分:0)

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

也许有用:http://pubs.opengroup.org/onlinepubs/009695399/functions/rand.html

答案 6 :(得分:-3)

指定原因1是因为如果种子设置为零,某些随机数生成器将卡在零。例如移位寄存器和乘法同余类型,即r(n+1) = (A * r(n))mod M

许多C实现使用线性同余r(n+1) = (A * r(n) + B) mod M,B&lt;&gt; 0不会卡住。