C 语言随机数与模拟
更新时间:2026-08-26。本文是
languages/c/主题高手层的骨架文档(占位),完整展开将在后续批次补齐。
本文要回答的问题
rand()是真随机吗?为什么"每次运行都一样"?- 怎么生成 [a,b] 区间的整数、均匀浮点数?
- 蒙特卡洛模拟怎么用随机数"算"出圆周率?
一、rand 的局限
rand() 是伪随机:由种子(seed)经线性同余等算法生成,序列确定。
| 问题 | 说明 |
|---|---|
| 未播种 | 默认种子固定,每次运行序列相同 |
| 周期有限 | 典型 2^31,大规模模拟可能重复 |
| 低位质量差 | rand() % N 分布可能不均匀 |
| 不保证密码安全 | 别用于安全场景 |
可复现性是特性不是 bug:固定种子(srand(42))让实验可重放——对调试和测试反而友好。
二、常用生成器
| 需求 | 方案 |
|---|---|
| 简单可复现 | srand(seed) + rand() |
| 更好质量 | POSIX random(),或 C11 rand_r |
| 密码学安全 | getrandom()//dev/urandom |
| [a,b] 整数 | a + rand() % (b-a+1)(注意偏差) |
| [0,1) 浮点 | (double)rand() / (RAND_MAX + 1.0) |
三、蒙特卡洛模拟
用随机采样逼近精确值——例如估算圆周率:正方形内随机撒点,统计落入内切圆的占比 × 4。
c
for (i = 0; i < N; i++) {
double x = (double)rand() / RAND_MAX; /* [0,1) */
double y = (double)rand() / RAND_MAX;
if (x*x + y*y <= 1.0) in_circle++;
}
pi ≈ 4.0 * in_circle / N;点越多越逼近,误差 ~1/√N。应用:积分近似、风险模拟、算法调参(配合 算法复杂度)。
四、与入门层的衔接
一句话总结
rand 是"种子决定的伪随机":要可复现就固定种子、要质量就换 random/urandom、要区间分布就按需映射——蒙特卡洛正是把伪随机变成"近似计算工具"的经典玩法。
本文为骨架文档:核心结构已就位,示例代码与实测数据将在后续批次补齐。