这是一个小程序:
#include <iostream>
#include <cstdlib>
using namespace std;
int main() {
long x = rand();
cout << x << endl;
}
它始终显示41
。但如果我修改程序,
#include <iostream>
#include <cstdlib>
using namespace std;
int main() {
for( int i = 0 ; i <= 9 ; i++ ) {
long x = rand();
cout << x << endl;
}
}
输出符合预期。随机数集。 的输出:
41
18467
6334
26500
19169
15724
11478
29358
26962
24464
但是为什么我在运行第一个程序时获得相同的数字 rand
实际上如何运作?
答案 0 :(得分:3)
您需要使用srand
为随机数生成器播种。
通常用以下方法完成:
srand(time(0));
如果每秒都有不同的系列就足够了。
time
函数只返回自纪元1970-01-01 00:00:00 +0000(UTC)以来的当前时间(秒)。
答案 1 :(得分:3)
编译器中内置的随机数发生器通常是伪随机数发生器。它们通常使用递归方程来生成下一个随机数并使用种子生成第一个随机数。 Check this link
为避免与第一个具有相同的随机数,您需要更改种子。同样,相同的种子将给出相同的初始随机数以及相同的随机数序列。因此,每次运行程序/线程时都应该更改种子。
要设置种子,您需要拨打srand()。每次调用srand()
时更改种子值的最佳方法是使用当前时间戳:time(0)
。
答案 2 :(得分:2)
来自:http://www.gnu.org/s/hello/manual/libc/ISO-Random.html
功能:void srand(unsigned int seed)
此函数将种子建立为新系列伪随机数的种子。如果在使用srand建立种子之前调用rand,则使用值1作为默认种子。
如果您在srand
中提供相同的种子,您将始终获得相同的数字序列。如果您从未致电srand
,那么每次运行您的应用程序时,您将始终获得相同的序列。
播种rand
的一个常见技巧是使用time(0)
- 基本上读取系统的时钟。这在一个简单的应用程序中很好,只需要“大多数是随机的”。
但是,当真正的随机性非常重要时:
请注意,您不应该只是在必须加密安全的应用程序中从系统时间中播种(例如,进行身份验证哈希计算的内容),或者具有强大的随机性保证(例如,用于真钱的赌博游戏)。 / p>
事实上,您不应该在这样的应用程序中使用rand
。相反,你应该使用不同的随机函数;可能是特定于操作系统的(专门用于加密),或使用真实的随机数源。