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

大範圍隨機數生成與等概率保證:C 語言實戰探討

     編輯:關於C語言

標準庫 rand() 僅提供 0~32767 範圍,無法滿足大範圍隨機需求。本文系統分析五種擴展方案,證明「按位組合 + 捨棄法」能同時滿足大範圍與等概率要求,並給出完整 C 實現代碼。

需求與背景

  • 生成指定上限 range 內的隨機整數(含 0,不含 range)
  • 每個數值出現概率嚴格相等
  • rand() 基礎範圍 0~32767,假設其均勻分佈

五種方案深度剖析

1. 兩個 rand 相乘:rand() * rand()

範圍可達 ~10 億,但嚴重破壞等概率:大質數永不出現,合數頻率極高,不可用。

2. 按位組合法

將上限轉為十進位位數,逐位生成 0~9 隨機數拼湊。例:上限 999,999,999 生成 9 位數。但若上限非 999... 形式(如 60,000),生成的 97,863 會超出範圍,需後續處理。

3. 求餘法:生成數 % range

結果落在範圍內,但概率不均。以 60,000 為例,0~39,999 出現概率 2/100,000,40,000~59,999 僅 1/100,000。

4. 逐位檢驗法

逐位生成 0~對應上限位數值。上限 51,782 時,第二位上限為 1,導致 33,216 等數永不可生成,失效。

5. 捨棄法(結合按位組合)✓

按位組合生成指定位數數值,若超出 range 則捨棄重生。數學證明:捨棄無效樣本不改變有效樣本相對概率,完美保證等概率。

完整 C 實現代碼


// 生成 0~9 單位隨機數
static __inline int min_rand() {
    return rand() % 10;
}

/**
 * 生成 [0, range) 等概率隨機數
 * @param range 上限(不包含)
 * @return 隨機整數
 */
int my_rand(const int range) {
    short bit = 0;
    int tempt = range;
    int rand_data = 0;

    // 計算十進位位數
    while (tempt > 0) {
        bit++;
        tempt /= 10;
    }

    // 按位組合生成隨機數
    while (bit--)
        rand_data = 10 * rand_data + min_rand();

    // 捨棄法:超出範圍遞歸重生
    if (rand_data >= range)
        return my_rand(range);

    return rand_data;
}

下限擴展

若需 [min, max) 區間,只需 min + my_rand(max - min) 即可。

本文出自「鄒輝」博客,轉載請保留出處:原文鏈接

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