

新闻资讯
技术学院现代C++推荐用std::random_device和std::mt19937替代rand():前者提供真随机种子,后者为高质量伪随机引擎;须用random_device初始化mt19937,配合uniform_int_distribution等分布对象生成指定范围的均匀随机数,避免取模破坏均匀性。
std::random_device 和 std::mt19937 生成高质量随机数现代 C++ 推荐弃用 rand(),改用 `std::random_device 提供真随机种子(通常来自系统熵),std::mt19937 是高效、周期长的伪随机数
引擎。
常见错误是直接用 std::mt19937{} 默认构造——它用固定种子,每次运行结果都一样。
std::random_device 初始化引擎,例如 std::mt19937 gen{std::random_device{}()}
std::mt19937 适合 32 位整数;若需 64 位,用 std::mt19937_64
gen,否则可能因构造开销或种子重复影响性能和随机性std::uniform_int_distribution 生成指定范围整数引擎只负责产出均匀分布的原始整数(如 uint32_t),要映射到自定义区间(比如 [1, 6] 模拟骰子),必须配合分布对象。直接对 gen() 结果取模(% 6 + 1)会破坏均匀性,尤其当范围不能整除引擎最大值时。
示例:生成 [10, 99] 的随机两位整数
std::mt19937 gen{std::random_device{}()};
std::uniform_int_distribution dist(10, 99);
int x = dist(gen); // 每次调用都返回一个符合分布的 int
int 必须与传入的上下界类型一致,否则编译失败dist(a, b) 包含 a 和 b 两个端点rand() 和 srand(time(nullptr))
rand() 是 C 风格遗留函数,存在多个硬伤:低序位随机性差、最大值由 RAND_MAX 限定(常为 32767)、无法指定分布、且 srand() 只能设一次种子——如果程序启动太快(比如被脚本快速连启多次),time(nullptr) 返回相同值,导致多进程生成完全相同的随机序列。
usleep(1000) 或用 getpid() 混合,也无法解决底层算法缺陷rand() 生成的序列容易被预测,std::mt19937 则更可靠rand() 实现甚至不是线性同余,但依然缺乏标准分布支持std::uniform_real_distribution
整数分布不能直接用于 float 或 double;必须显式选用实数分布。注意:它默认生成半开区间 [a, b),即包含 a,不包含 b。
示例:生成 [0.0, 1.0) 的 double
std::mt19937_64 gen{std::random_device{}()};
std::uniform_real_distribution dist(0.0, 1.0);
double d = dist(gen);
dist(a, std::nextafter(b, INFINITY)),但通常没必要double 分布而非 float,避免舍入偏差累积static_cast(rand()) / RAND_MAX ,它分辨率极低且分布不均gen.seed() 或序列化其内部数组),而不是分布。