C语言是否总是生成相同的随机序列?

4
我运行了一个调用rand()函数四次的程序。我使用模运算符将范围限制在1-6之间。生成的整数是2、5、4和2。我重新运行了程序,得到了相同的数字。然后我创建了一个全新的程序,也调用了rand()函数四次,但我仍然得到整数序列2、5、4、2。然后我关闭计算机,重新启动,创建了另一个调用rand()函数四次的新程序,仍然得到序列2、5、4、2。
我知道你需要使用srand()来“种子”RNG,从不同的点开始生成随机数,但我只是好奇:忘记种子这个问题,rand()函数生成的序列是否与安装、编译器和/或操作系统有关?例如,以下任何一项是否会导致不同的序列:
  • 在我的计算机上卸载并重新安装C编译器
  • 在我的计算机上安装和使用不同的C编译器
  • 在其他人使用相同编译器的计算机上运行该程序?
  • 在其他人使用不同编译器(可能是不同操作系统)的计算机上运行该程序?
还是所有的C编译器都使用相同的RNG算法,因此从开始(伪)随机序列对于每个人都是相同的?

1
可能是What common algorithms are used for C's rand()?的重复问题。 - Eugene Sh.
为什么不直接参考C标准呢? - too honest for this site
@Olaf,因为我的问题没有被规范明确地解决,这使得答案对于初学者来说很难推断。而且,因为这个网站上至少有一些善良的人能够理解初学者并愿意提供帮助。 - yroc
这个问题在我发布的标准链接中得到了确切的回答。只需继续阅读有关可重复性的srand部分即可。至于生成相同序列:标准是否强制执行特定算法?请注意,该链接不仅是规范,而且是国际标准(嗯,最终草案,但没有显著差异;标准是付费的)。 - too honest for this site
3个回答

6
如果你没有调用srand,C会这样说:
(引用)
因此,如果你的rand函数(C标准中未指定,取决于实现)是一个算法伪随机数生成器,如果没有调用srand,很可能会再次得到相同的序列。

但是这并没有回答“2、5、4、2”序列来自何处的问题。(为什么恰好是 2、5、4、2?) - idmean
1
@idmean 我认为我们对他的问题没有相同的理解。 - ouah
@ouah,所以如果rand()未指定并留给实现,您能推测出不同编译器、不同机器、不同操作系统等会生成什么吗? - yroc
2、5、4、2这个序列来自于特定的rand()算法,它使用种子1并结合某种算法将值限制在1到6之间。对于那个特定的编译器/版本,如果种子为1,那么这个序列总是相同的。对于另一个编译器/版本,可能会使用不同的算法或起始值,因此序列可能完全不同。 - Retired Ninja
2
@yroc,rand有许多实现方式,因此您不能指望不同的系统、不同的libc或不同的libc版本实现相同的算法。 - ouah

0
当你说“运行程序四次”时,听起来像是每个种子只获取一次rand()的值,这将不会是一个随机序列。要获得随机序列,您需要在同一程序运行中调用srand()一次和多次调用rand()。 如果您需要跨程序执行的随机序列,则必须使用类似/dev/random的东西。

我没有说我运行了程序四次。我是说我运行了一个调用rand()函数四次的程序。 - yroc
是的,英语在这里有点模糊。在这种情况下,很可能是您在srand()中使用的值。 - Lee Daniel Crocker

0
抛开种子生成器不谈,rand()函数产生的序列是否与安装、编译器和/或操作系统有关?
这取决于特定库的实现方式,它可以是编译器安装的一部分或单独安装的。不同的库实现可能会产生不同的序列。我期望在两个不同系统上使用相同的库实现会给出相同的值序列,但这是基于它不使用本地系统信息作为伪随机数生成算法的一部分。
唯一的要求是相同的种子值必须始终产生相同的序列,而且如果没有先调用srand()函数而直接调用rand()函数,则rand()函数应当像已经使用了种子1一样工作。

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