但这些似乎是对 rand 函数的旧批评
这可能是一个挑剔,但我想指出我认为这个逻辑的缺陷。编译器通常对更改程序行为极为保守,即使该行为(愚蠢地)取决于实现细节。
对于您熟悉的大型编译器来说,这可能会也可能不会,但可以想象,出于兼容性原因,编译器会保留损坏的遗留 RNG。
我的macbook上的以下程序:
#include <cstdlib>
#include <iostream>
using namespace std;
int main() {
srand(1);
for (int i = 0; i < 20; ++i) {
cout << (i > 0 ? ", " : "") << rand();
}
cout << endl;
return 0;
}
产生输出
16807, 282475249, 1622650073, 984943658, 1144108930, 470211272, 101027544, 1457850878, 1458777923, 2007237709, 823564440, 1115438165, 1784484492, 74243042, 114807987, 1137522503, 1441282327, 16531729, 823378840, 143542612
您可以在 OEIS 中查找:https ://oeis.org/A096550 ,它是序列 16807nmod(231−1).
在 SmallCrush RNG 测试下这是如何做到的(在 TestU01 库中):
========= Summary results of SmallCrush =========
Version: TestU01 1.2.3
Generator: ulcg_CreateLCG
Number of statistics: 15
Total CPU time: 00:00:08.05
The following tests gave p-values outside [0.001, 0.9990]:
(eps means a value < 1.0e-300):
(eps1 means a value < 1.0e-15):
Test p-value
----------------------------------------------
1 BirthdaySpacings eps
2 Collision eps
6 MaxOft eps
----------------------------------------------
All other tests were passed
据我所知,根本没有充分的理由假设这rand()
可能没问题。如果你假设不是这样,你通常最终会编写一些极其不可移植的代码,这些代码会在不同系统上的不同编译器下崩溃。