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

rand() 返回值範圍深度解析:RAND_MAX、均勻分布與跨平台差異

     編輯:關於C語言

標準規定(C99/C11)

  • 原型:int rand(void);
  • 返回範圍:[0, RAND_MAX],包含兩端。
  • RAND_MAX:宏常量,至少 32767(即 2^15-1)。具體值由實現定義。
  • 分布:偽隨機,統計上近似均勻分布,但非加密安全。

主流平台實際值

平台/庫RAND_MAX備註
glibc (Linux)2147483647 (2^31-1)31 位,高質量
MSVC (Windows)32767 (2^15-1)15 位,質量較低
musl libc2147483647同 glibc
嵌入式 newlib32767 或 65535視配置

常見誤區與正確用法

誤區 1:rand() % N 產生 [0, N-1]

問題:若 RAND_MAX + 1 不能被 N 整除,分布不均勻(模數偏差)。

正確:拒絕採樣法


int rand_range(int n) {  // [0, n-1]
    int limit = RAND_MAX - (RAND_MAX + 1) % n;
    int r;
    do { r = rand(); } while (r > limit);
    return r % n;
}

誤區 2:srand(time(NULL)) 多次調用

問題:同一秒內多次調用產生相同序列。

正確:程序啟動時僅調用一次srand;高並發/多線程用 thread_local 種子或 rand_r。

誤區 3:浮點數縮放 (double)rand()/RAND_MAX

問題:精度有限,無法覆蓋所有浮點數;RAND_MAX 較小時分布稀疏。

現代替代:C11 <random.h>(若支持)或第三方庫(PCG、xoshiro256**)。

線程安全版:rand_r


unsigned int seed = 12345;
int r = rand_r(&seed);  // 可重入,每線程持有獨立 seed

測試代碼:檢視當前平台 RAND_MAX


#include <stdio.h>
#include <stdlib.h>
#include <limits.h>

int main() {
    printf("RAND_MAX = %d\n", RAND_MAX);
    printf("INT_MAX  = %d\n", INT_MAX);
    // 簡單分布測試
    long long cnt[10] = {0};
    for (int i = 0; i < 1000000; ++i) cnt[rand() % 10]++;
    for (int i = 0; i < 10; ++i) printf("%d: %lld\n", i, cnt[i]);
    return 0;
}

總結

  • rand() 返回 [0, RAND_MAX],RAND_MAX ≥ 32767。
  • 跨平台差異巨大,**切勿假設具體值**。
  • 需均勻分布時使用拒絕採樣或現代 <random>。
  • 加密場景**嚴禁使用**,改用 /dev/urandom、CryptGenRandom 或專用 CSPRNG。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved