首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C >> 關於C

C/C++ 隨機數生成完整指南:rand/srand/time 機制、範圍控制、浮點數與常見陷阱

     編輯:關於C

核心函數與頭文件


#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;
}

進階:C++11 <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**。理解偽隨機本質、種子機制、取模偏差、線程安全,是正確使用隨機數的前提。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved