2

这与这个问题有关-C++ 中的随机数生成...第一个数字不是很随机

#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.54xxxx。

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

编辑:只有第一个结果具有前三个相同的数字。其余的是“随机查找”。此外,生成器使用 srand() 播种(在上面代码示例的第一行)。

4

1 回答 1

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 中一些定义更严格的生成器。(如果你不使用 C++11,你可以从 Boost 获取它们。)

于 2013-07-11T16:30:33.823 回答