1 为什么你的随机数“不随机”?
今天,我们通过一个简单的rand()
小程序,带你看透C语言随机数生成的底层逻辑!你是否遇到过这样的问题:
-
随机数总在固定范围内重复?
-
程序运行多次结果完全一样?
-
为什么
rand() % 100
可能“不公平”?
别急,本文将用代码+
源码分析,带你彻底解决这些问题!
2 实战
#include <stdio.h>
#include <stdlib.h>
int main() {
int a = rand() % 100;
printf("%d\n", a);
int cnt = 0;
while (a != 12) {
a = rand() % 100;
printf("试了%d次了,X现在是:%d\n", cnt, a);
cnt++;
}
printf("RAND_MAX = %d\n", RAND_MAX);
return 0;
}
3 代码问题:为什么程序可能“卡死”或结果重复?
问题1:随机数“不随机”
关键点:rand()
的随机性依赖于种子(seed)。
代码问题:未调用srand()
初始化种子
→ 导致每次运行程序时,rand()
生成的序列完全相同!
问题2:rand() % 100
的“不公平性”
数学陷阱:若RAND_MAX + 1
不能被100整除(如32768 % 100 ≠ 0
),则余数分布不均匀!
→ 例如:32768/100 = 327余68
,前68个数的概率更高!
4 源码分析
1 rand()
的底层实现:线性同余生成器(LCG)
- 公式:
next = (a * current + c) % m
a
:乘数(如1103515245
)c
:增量(如12345
)m
:模数(如2^31
)
- 问题:LCG是伪随机数生成器(PRNG),种子相同则序列相同!
2 srand()
的作用:播种随机性
- 函数原型:
void srand(unsigned int seed);
- 解决方案:用当前时间作为种子,确保每次运行结果不同!
srand(time(NULL)); // 需包含<time.h>
5改进后代码:
#include <stdio.h>
#include <stdlib.h>
#include <time.h> // 新增头文件
int main() {
srand(time(NULL)); // 初始化种子!
int a = rand() % 100;
printf("%d\n", a);
int cnt = 0;
while (a != 12) {
a = rand() % 100;
printf("试了%d次了,X现在是:%d\n", cnt, a);
cnt++;
}
printf("RAND_MAX = %d\n", RAND_MAX);
return 0;
}