为什么rand()/ double(RAND_MAX)的第一个结果不是随机的

时间:2013-07-11 16:18:34

标签: c++ random

这与此问题有关 - random number generation in C++ ... first number not very random

#include <iostream>
#include <stdlib.h>
#include <time.h>
using namespace std;

int main()
{
srand((unsigned int)time(NULL));

cout << rand() / double(RAND_MAX) << endl;
cout << rand() / double(RAND_MAX) << endl;
cout << rand() / double(RAND_MAX) << endl;
cout << rand() / double(RAND_MAX) << endl;
cout << rand() / double(RAND_MAX) << endl;

return 0;
}

如果一遍又一遍地运行二进制文件(.exe),您会注意到第一个结果始终具有相同的前三个数字。例如。每次运行总是0.54xxxxx。

不,这不是因为我发现没有任何模式。每次运行之间等待几秒钟也无济于事。

修改:只有第一个结果才有第一个相同的三个数字。其余的都是“随意看”。此外,生成器使用srand()播种(在上面的代码示例的第一行)。

1 个答案:

答案 0 :(得分:6)

标准未指定rand的随机性。最 生成器将使用种子初始化静态变量, 并以一种应该的方式从中计算下一个值 “出现”随机(但当然是完全确定的)。 我的猜测是你机器上的实现返回了 静态变量的旧值,等于种子的 第一次通过。 (这种情况让我感到惊讶,这是常见的 返回静态的新值。)

无论如何,这是一个实施质量的问题。 (我在VC ++ 11中看到了相同的内容,但g ++没有。)

编辑:

快速测试看看种子的变化如何影响第一种 号码返回:

for ( int i = 1; i <= 10; ++ i ) {
    std::srand( i );
    std::cout << i << ": " << std::rand() << std::endl;
}

VC ++ 11的输出:

1: 41
2: 45
3: 48
4: 51
5: 54
6: 58
7: 61
8: 64
9: 68
10: 71

使用g ++ 4.7.2(CygWin版本):

1: 1481765933
2: 816048218
3: 150330503
4: 1632096437
5: 966378722
6: 300661007
7: 1782426941
8: 1116709226
9: 450991511
10: 1932757444

你说你在Code Blocks下用g ++看到了这个: 我只能猜测Code Blocks会设置为g ++ 使用Microsoft库,而不是GNU库 (通常是更好的解决方案)。

无论如何,解决方案很简单:替换你现在的单行 用于为发电机播种:

std::srand( std::time( NULL ) );
std::rand();        // throw out first value...

如果您需要相对较好的随机数,请删除std::rand 完全赞成一些更严格的定义 C ++中的生成器11。 (如果不是,你可以从Boost获得它们 使用C ++ 11。)