即使播种,C 中的 rand() 函数也不是随机的

ᴘᴀɴ*_*ᴛɪs 5 c random

这很可能是与机器有关的问题,但我无法弄清楚可能是什么问题。

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

int main(int argc, char** argv) {

  srand(time(NULL));
  int r1 = rand();
  int r2 = rand();
  printf("%d %d\n", r1, r2);
}
Run Code Online (Sandbox Code Playgroud)

我编译上面的代码使用

gcc randd.c
Run Code Online (Sandbox Code Playgroud)

然后手动运行几次,第一个数字看起来非常相似,而第二个数字似乎是随机的:

1025720610 1435057801
1025737417 1717533050
1025754224 2000008299
1025771031 134999901
1025787838 417475150
Run Code Online (Sandbox Code Playgroud)

第一次调用rand()似乎与时间密切相关,并且随着时间的推移严格增加。关于为什么会发生这种情况或如何解决它的任何想法?

这发生在 OSX 10.11

Tho*_*son 2

  1. rand()非常糟糕,如果可能的话避免它。在任何好的 RNG 中,即使种子很接近(汉明距离),第一个值也将与随机值无法区分。rand但情况并非如此。
  2. 如果必须使用 rand,那么最好使用比时间更高的熵来为其播种,并rand()多次调用而不是重新播种-调用-重新播种。

以 2 为例,请考虑:

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

int main(int argc, char** argv) {
  int t=time(NULL);
  srand(t);

  for(int i=0; i < 10; i++) {
    float r = (float)rand()/(float)(RAND_MAX);
    printf("%f\n", r);
  }
}
Run Code Online (Sandbox Code Playgroud)

结果:

0.460600
0.310486
0.339473
0.519799
0.258825
0.072276
0.749423
0.552250
0.665374
0.939103
Run Code Online (Sandbox Code Playgroud)

它仍然是一个糟糕的 RNG,但至少当你允许它使用内部状态而不是给它另一个类似的种子时,范围会更好。