#include // rand, srand, RAND_MAX
#include // time
// C++: #include ,
rand() 生成 0 到 RAND_MAX
for (int i = 0; i < 10; i++)
printf("%d\n", rand()); // 0 ~ 2147483647 (通常)
關鍵點:RAND_MAX 定義於 <stdlib.h>,最小 32767,通常 2147483647 (2^31-1)。
// [0, 9] 即 10 以內整數
rand() % 10;
// [min, max] 通用公式
min + rand() % (max - min + 1);
// 示例:[100, 200]
100 + rand() % 101;
缺陷:rand() 低位隨機性差,取模引入統計偏差(當範圍不整除 RAND_MAX+1)。關鍵場景建議用拒絕採樣或 C++11 <random>。
// [0.0, 1.0) 標準方法
(double)rand() / RAND_MAX;
// 兩位小數 [0.00, 1.00]
rand() % 10001 / 10000.0; // 注意 10000.0 強制浮點除法
// 通用 [min, max) 浮點
min + (max - min) * (double)rand() / RAND_MAX;
srand() 與 time()rand() 是偽隨機數生成器(線性同餘法 LCG)。無種子時默認種子=1,**每次運行產生完全相同序列**。
#include
srand((unsigned int)time(NULL)); // 以秒級時間為種子
// 或 time(0)
效果:每秒不同種子,序列不同。同一秒內多次運行種子相同。
// 結合進程 ID、線程 ID、高精度時間
struct timespec ts;
clock_gettime(CLOCK_REALTIME, &ts);
srand((unsigned int)(ts.tv_nsec ^ getpid() ^ (uintptr_t)&ts));
#include
#include
#include
int main() {
// 1. 初始化種子(程序啟動一次即可)
srand((unsigned)time(NULL));
// 2. 生成 10 個 [1, 100] 整數
puts("10 隨機整數 [1,100]:");
for (int i = 0; i < 10; i++)
printf("%d ", 1 + rand() % 100);
putchar('\n');
// 3. 生成 5 個 [0.0, 1.0) 浮點數
puts("5 隨機浮點數 [0.0,1.0):");
for (int i = 0; i < 5; i++)
printf("%.4f ", (double)rand() / RAND_MAX);
putchar('\n');
return 0;
}
<random> 現代方案(強烈推薦)
#include
#include
int main() {
// 1. 引擎:梅森旋轉 MT19937,種子用 random_device
std::random_device rd;
std::mt19937 gen(rd());
// 2. 分佈:均勻整數 [1, 100]
std::uniform_int_distribution<> dis_int(1, 100);
for (int i = 0; i < 10; i++)
std::cout << dis_int(gen) << ' ';
std::cout << '\n';
// 3. 分佈:均勻浮點 [0.0, 1.0)
std::uniform_real_distribution<> dis_real(0.0, 1.0);
for (int i = 0; i < 5; i++)
std::cout << dis_real(gen) << ' ';
std::cout << '\n';
// 4. 正態分佈 (高斯) μ=0, σ=1
std::normal_distribution<> dis_norm(0, 1);
std::cout << "Normal: " << dis_norm(gen) << '\n';
return 0;
}
優勢:統計質量高、分佈豐富、線程安全(引擎可局部)、無取模偏差、標準化可移植。
| 錯誤 | 後果 | 修正 |
|---|---|---|
循環內重複 srand(time(NULL)) | 同一秒內產生相同序列 | 程序啟動一次調用 srand |
rand() % N 當 N 較大時統計偏差 | 分佈不均 | 用拒絕採樣或 C++11 uniform_int_distribution |
浮點除法寫成 rand() / RAND_MAX (整數除法) | 恒為 0 | 強制轉換 (double)rand() / RAND_MAX |
多線程共用 rand() (全局狀態) | 競爭條件、序列破壞 | 用 rand_r (POSIX) 或 C++11 線程局部引擎 |
加密場景用 rand() | 可預測,極不安全 | 用 /dev/urandom、CryptGenRandom、std::random_device |
rand()/srand()/time() 是 C 語言經典隨機數組合,**適合教學、測試、非關鍵場景**;生產環境、科學計算、加密、多線程、**強制遷移至 C++11 <random> 或平台 CSPRNG**。理解偽隨機本質、種子機制、取模偏差、線程安全,是正確使用隨機數的前提。