随机数使用
随机数
随机数的生成对于很多随机数算法非常重要
在C++中,mt19937_64和srand(time(0))(配合rand())是两种不同的随机数生成方式,它们分别属于现代C++随机数库和传统的C风格随机数生成方法。以下是它们的详细介绍、区别以及适用场景。
mt19937_64(梅森旋转算法)
特点
- 高质量随机数:基于梅森旋转算法(Mersenne Twister),周期极长((2^{19937}-1)),适用于需要高质量随机数的场景。
- 64位随机数:生成的是64位无符号整数(
uint64_t),范围更大。 - 现代C++风格:属于
<random>库,支持多种随机分布(均匀分布、正态分布等)。 - 线程安全:每个
mt19937_64实例独立运行,适合多线程环境。
基本用法
#include <random>
#include <iostream>
int main() {
std::mt19937_64 rng(std::random_device{}()); // 使用随机设备初始化种子 也可用mt19937_64 rnd(time(0))
for (int i = 0; i < 5; i++) {
std::cout << rng() << "\n"; // 生成64位随机数
}
return 0;
}
输出示例
14514284786278117030
4620546740167642908
13199598094361884370
16793137390881808272
...
适用场景
- 密码学(需要高质量随机数)
- 模拟仿真(需要长周期随机数)
- 哈希函数(如本题的随机哈希)
- 游戏开发(随机地图生成、AI行为)
srand(time(0))+rand()(传统C随机数)
特点
- 简单易用:属于C标准库(
<cstdlib>),代码简短。 - 低质量随机数:基于线性同余生成器(LCG),周期较短(通常 (2^{31})),随机性较差。
- 32位随机数:
rand()返回int,范围通常是0到RAND_MAX(通常32767)。 - 全局状态:
srand()设置种子后,所有rand()调用共享同一个状态,不适合多线程。
基本用法
#include <cstdlib>
#include <ctime>
#include <iostream>
int main() {
std::srand(std::time(0)); // 用当前时间初始化种子
for (int i = 0; i < 5; i++) {
std::cout << std::rand() << "\n"; // 生成随机数
}
return 0;
}
输出示例
1804289383
846930886
1681692777
1714636915
...
适用场景
- 简单随机需求(如随机排序、简单游戏)
- 快速原型开发(不需要高质量随机数)
- 教学示例(因为代码简单)
- 关键区别
| 特性 |mt19937_64|srand(time(0))+rand()|
|------|-------------|----------------|
| 随机性质量 | 高(梅森旋转) | 低(线性同余) |
| 周期长度 | (2^{19937}-1) | (2^{31}) |
| 生成位数 | 64位 | 32位 |
| 随机数范围 | 0 ~ (2^{64}-1) | 0 ~RAND_MAX(通常32767) |
| 线程安全 | 是(每个实例独立) | 否(全局状态) |
| 现代C++支持 | 是(<random>) | 否(C风格) |
- 如何选择?
| 场景 | 推荐方法 |
|------|---------|
| 需要高质量随机数(哈希、密码学) |mt19937_64|
| 多线程环境 |mt19937_64(每个线程独立实例) |
| 简单随机需求(如随机排序) |rand()|
| 需要特定分布(如正态分布) |<random>库(std::normal_distribution) |
| 兼容旧代码 |rand()|
- 代码示例对比
(1) 生成随机数
// mt19937_64
std::mt19937_64 rng(std::random_device{}());
u64 random_num = rng();
// rand()
std::srand(std::time(0));
int random_num = std::rand();
(2) 生成范围随机数
// mt19937_64 + 均匀分布
std::uniform_int_distribution<int> dist(1, 100);
int num = dist(rng);
// rand() 取模(不推荐,有偏差)
int num = std::rand() % 100 + 1; // 可能不均匀
(3) 生成浮点数
// mt19937_64 + 均匀浮点分布
std::uniform_real_distribution<double> dist(0.0, 1.0);
double num = dist(rng);
// rand() 转换(不推荐)
double num = (double)std::rand() / RAND_MAX; // 精度低
- 结论
- 优先使用
<random>库(mt19937_64),因为:- 随机性更好
- 支持多种分布
- 线程安全
rand()仅适用于简单需求,如:- 快速测试
- 旧代码兼容
- 不需要高质量随机数的场景

浙公网安备 33010602011771号