繁体   English   中英

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

[英]rand() function in C is not random even when seeded

这很可能是机器相关的问题,但我无法弄清楚可能出现的问题。

#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);
}

我使用编译上面的代码

gcc randd.c

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

1025720610 1435057801
1025737417 1717533050
1025754224 2000008299
1025771031 134999901
1025787838 417475150

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

这发生在OSX 10.11上

  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);
  }
}

结果如下:

0.460600
0.310486
0.339473
0.519799
0.258825
0.072276
0.749423
0.552250
0.665374
0.939103

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

这正是你应该期待的。 没有“随机数”这样的东西。 只有数字序列具有随机分布。 rand()函数生成这样的序列,但你没有给它机会,因为你不断重新播种它。 rand()生成的第一个数字很可能只是种子或种子本身的某些功能。 一些rand()函数可能会对种子进行散列以隐藏它,但这并不能使它们更好,因为rand()的契约是产生一个随机序列

如果你需要一系列随机数来运行多个程序,你必须做类似的事情(a)写一个调用srand()一次的程序,然后多次调用rand() ,并让你的其他程序要求IPC上该程序的随机数; (b)使用像/dev/urandom这样的东西; (c)使用类似random.org东西。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM