// 假設原始代碼類似:
int r = rand() / 1000; // 或 rand() % 1000
rand() 返回 [0, RAND_MAX] 範圍內的偽隨機整數,RAND_MAX 通常為 32767(16 位有符號整數最大值)。
當使用 rand() / 1000 時:
[0, 32](因 32767/1000 = 32.767)同理,rand() % 1000 也會導致 0~767 比 768~999 概率高(因 32768 % 1000 = 768)。
#include
#include
int main() {
// 1. 隨機數引擎:梅森旋轉算法,周期 2^19937-1
std::mt19937 gen(std::random_device{}()); // 硬件熵源播種
// 2. 分布適配器:均勻整數分布 [0, 999]
std::uniform_int_distribution dist(0, 999);
// 3. 生成
for (int i = 0; i < 10; ++i) {
std::cout << dist(gen) << ' ';
}
// 輸出示例:842 117 934 521 309 762 45 688 213 991
return 0;
}
| 特性 | rand()/srand() | <random> |
|---|---|---|
| 分布均勻性 | 差(模除/整除偏差) | 數學保證均勻 |
| 周期 | ~2^31 | ~2^19937 (mt19937) |
| 線程安全 | 否(全局狀態) | 是(引擎對象可復制/移動) |
| 分布類型 | 僅均勻整數 | 均勻/正態/泊松/指數/伯努利等 20+ 種 |
| 可移植性 | RAND_MAX 實現定義 | 標準規範行為一致 |
若受限於 C89/C99 標準,無法使用 <random>:
// 拒絕採樣法消除模除偏差
int rand_uniform(int max) { // 生成 [0, max-1]
if (max <= 0) return 0;
const int RAND_LIMIT = RAND_MAX - (RAND_MAX % max);
int r;
do {
r = rand();
} while (r >= RAND_LIMIT); // 拒絕超出完整倍數範圍的值
return r % max;
}
// 使用示例:生成 [0, 999]
int r = rand_uniform(1000);
原理:丟棄導致分布不均的「尾部剩餘值」,確保每個輸出值對應相同數量的原始隨機數。
std::random_device 直接讀取 /dev/urandom 或 Windows CNG API,或使用 OpenSSL RAND_bytes()mt19937 實例,避免鎖競爭mt19937 gen(12345) 確保結果可復現std::uniform_real_distribution(0.0, 1.0) rand() / 1000 或 rand() % 1000 存在明顯統計偏差,現代 C++ 必須使用 <random> 庫。C 環境下採用拒絕採樣修正。隨機數質量直接影響業務邏輯公平性(抽獎、分桶、負載均衡)與科學計算準確性,切勿輕視。