C/C++中生成随机序列——随机函数的选择和自我实现

本文讲述了在将Windows项目移植到Linux过程中,由于随机数生成函数的差异导致的问题。文章详细分析了标准库中的srand()和rand()函数,包括它们的原理、使用方法以及在不同平台上的行为。此外,作者还分享了自己实现的rand()函数,以确保在两个平台上得到相同的结果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、缘由

最近需要将windows下的项目移植到linux下,但因为项目使用到随机函数,导致最后两边的结果有些微差异,因此需要将两边随机函数统一来保证运行结果每一步能对应上。
大家常用的随机函数有srand()/rand();

二、srand()/rand()

1.项目中采用的随机数生成函数是 rand()。
rand()返回一随机,数值的范围在0至RAND_MAX 间。

它的内部实现是用线性同余法做的,产生的新随机数作为下一次随机数的种子,它不是真的随机数,因其周期特别长,故在一定的范围里可看成是随机的。
线性同余法的原理:
X_{n+1} = ( a * X_n + c ) mod m

windows 下RAND_MAX 为32767(16位)。
linux下为2147483647(32位)
如果不用srand()指定随机函数,指定默认情况下种子为1。

2.其用法为:
void srand(unsigned int seed);
int rand();

#include <stdlib.h>//rand()头文件
#include <time.h> //为了
srand((unsigned)time(NULL));//采用系统当前时钟作为种子
int num_rand = ra
### C++生成随机数的方法 #### 传统方法:`rand()` `srand()` 在 C++11 之前,C C++ 使用相同的伪随机生成机制,主要依赖于标准库中的两个函数——`rand()` `srand()`。 - 函数 `rand()` 返回一个介于 `[0, RAND_MAX]` 的整数值[^2]。 - 函数 `srand(unsigned int seed)` 设置随机生成器的种子值。如果不调用 `srand()` 或者多次运行程序时未重新设置种子,则每次执行都会返回相同的序列。 以下是使用这两个函数的一个简单例子: ```cpp #include <iostream> #include <cstdlib> // 包含 rand(), srand() #include <ctime> // 包含 time() int main() { std::srand(static_cast<unsigned>(std::time(0))); // 使用当前时间作为种子 for (int i = 0; i < 5; ++i) { std::cout << std::rand() % 100 << ' '; // 输出范围 [0,99] } return 0; } ``` 此代码片段展示了如何通过 `srand(std::time(0))` 来初始化随机数发生器,并利用 `rand()` 获取一系列不同的随机数。 #### 现代方法:C++11 `<random>` 库 自 C++11 起引入了一个更强大、灵活且高效的随机生成框架 —— `<random>` 头文件提供了丰富的类模板用于实现高质量的随机化操作[^4]。它主要包括两部分组件: 1. **随机数引擎**(Random Number Engines) - 如 `std::default_random_engine`, `std::mt19937`(Mersenne Twister),它们负责实际生产原始数据流; 2. **分布模型**(Distributions Models) - 像均匀分布 (`std::uniform_int_distribution`)、正态分布(`std::normal_distribution`)等用来调整这些基础输出使之满足特定需求。 下面是一个基于现代技术的例子,演示了如何创建并应用一个线程安全的标准 Mersenne twister 引擎以及离散型整数区间上的均布概率密度函数: ```cpp #include <iostream> #include <random> int main(){ // 定义 mt19937 发动机实例 std::random_device rd; // 非确定性的初始源 std::mt19937 gen(rd()); // 利用上述设备构建发动机 // 创建一个闭合区间的整数分布对象 std::uniform_int_distribution<> dis(1, 6); for(int n=0;n<10;++n){ // 打印模拟骰子投掷的结果 std::cout<<dis(gen)<<'\n'; } return 0; } ``` 该示例说明了如何借助 `<random>` 实现更为精确可控的随机过程。 --- ### 总结 对于旧版本编译环境或者小型项目来说,采用经典的 `rand()`/`srand()` 组合可能已经足够;然而,在追求更高性能指标或是跨平台兼容性考量下,推荐优先选用标准化程度更高的 C++11 及以后版本所提供的解决方案。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值