srand(1)和srand(0)之间有什么区别
我刚刚发现srand(1)
在调用srand
(如参考文献中定义)之前将C(++)的PRNG重置为状态的困难方式。 然而,种子0似乎做同样的事情,或者在调用srand
之前的状态似乎使用种子0.这两个调用之间有什么区别或者他们做同样事情的原因是什么?
例如这段代码( 在Ideone上执行 )
#include #include 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
这可能是一个实现细节。 标准要求随机种子1是特殊的,并且您的特定随机生成器算法的内部寄存器可能是零初始化的,因此导致种子(0)和种子(1)的相同随机序列。 我甚至打赌你的srand()实现的第一行看起来像:
if ( seed == 1 ) seed = 0;
强制符合标准的行为。
通常,rand()和srand()的随机数生成器不需要为不同的种子提供不同的序列,但是对于相同的种子使用相同的序列。 所以, 不要依赖不同的种子产生不同的随机序列 ,你应该没事。 如果没有,欢迎特定实施的乐趣。
glibc是如何做到的:
在glibc / stdlib / random_r.c的第181行附近 ,函数
__srandom_r
/* We must make sure the seed is not 0. Take arbitrarily 1 in this case. */ if (seed == 0) seed = 1;
但这就是glibc如何做到的。 这取决于C标准库的实现。
C和C ++标准都没有说明rand()
和srand()
实现的细节。 细节几乎完全取决于实现者。 C标准要求:
如果随后使用相同的种子值调用srand,则应重复伪随机数序列。 如果在对srand进行任何调用之前调用rand,则应该生成与第一次调用srand且种子值为1时相同的序列。
但它不包含任何要求不同种子必须产生不同序列的要求。 显然,在你的系统上,零和一的种子具有相同的效果。 我猜这是为了向某些软件提供向后兼容性,这些软件期望srand(0)
将PRNG重置为其初始状态。
如果seed设置为1,则将生成器重新初始化为其初始值,并生成与调用rand或srand之前相同的值。 取自srand参考
在阅读手册页时,它们都声明“如果没有提供种子值,则rand()函数会自动播种,值为1”。 这可能是您链接到状态的参考页面,其中播种1会重置状态。
对0和1两者进行播种的结果相同,很可能取决于实现,并且不应计入所有平台上。
srand()函数使用该参数作为后续调用rand()返回的新伪随机数序列的种子。 如果随后使用相同的种子值调用srand(),则应重复伪随机数序列。 如果在对srand()进行任何调用之前调用rand(),则应生成与首次调用种子值为1的srand()时相同的序列。
也许有用: http : //pubs.opengroup.org/onlinepubs/009695399/functions/rand.html
指定原因1是因为如果将种子设置为零,则某些随机数生成器将停留在零。 例如移位寄存器和乘法同余类型,即r(n+1) = (A * r(n))mod M
许多C实现使用线性同余r(n+1) = (A * r(n) + B) mod M
,B <> 0,它们不会被卡住。