C語言中隨機數的生成


剛好在找這方面的資料,看到了一片不錯的,就全文轉過來了,省的我以后再找找不到。

 

在C語言中,可以通過rand函數得到一個“偽隨機數”。這個數是一個整數,其值大於等於0且小於等於RAND_MAX。rand函數和常量RAND_MAX都定義在庫stdlib.h之中,這意味着必須在頭文件中包含庫stdlib.h才能使用rand函數和常量RAND_MAX。 

rand函數聲明為: 
int rand(void) 

//代碼示例 start 
#include <stdio.h> 
#include <stdlib.h> 

int main() 

    printf("%d %d\n", rand(), rand()); 

//代碼示例 end 

編譯運行以上代碼,將在屏幕顯示兩個隨機數。但多次運行這個程序,你會發現每次程序啟動后生成的兩個隨機數都是一樣的!可見,rand()生成的值並不隨機。 
標准庫(stdlib)中隨機數的一個可能的實現如下: 
//代碼示例 start 
#define RAND_MAX 0x7fff 
unsigned long int next = 1; 

int rand(void) 

    next = next * 1103515245 + 12345; 
    return (unsigned int)(next/65536) % RAND_MAX; 


/*srand函數:為rand函數設置種子數*/ 
void srand(unsigned int seed) 

    next = seed; 

//代碼示例 end 

由上可知,只要我們每次在程序運行開始時用srand設置好不同的nex值,那么程序每次運行都將得到不同是隨機序列。那又如何給srand傳入不同的數呢?隨機數?好吧,這下變成雞生蛋蛋生雞的問題了。其實不用那么復雜。我們只需要把當前的時間作為srand的參數傳入就好了。程序每次運行的時間點是肯定是不一樣的。 
要獲取當前時間,可以使用time庫中的time函數。示例如下: 
//代碼示例 start 
#include <stdio.h> 
#include <stdlib.h> 
#include <time.h> 

int main() 

    srand((int)time(0)); 
    printf("%d %d\n", rand(), rand()); 

//代碼示例 end 

編譯運行上述代碼,就能讓程序每次運行都得到不同的隨機值了。 

程序中time(0)函數返回值類型為time_t(time_t定義為長整型),time(0)返回從1970年1月1日零時零分零秒到目前為止所經過的時間,單位為秒。


好了,到目前為止,我們已經解決了如何在區間[0, RAND_MAX]內等概率隨機獲得一個整數的問題。那么又應該如何等概率的隨機獲取任意范圍內的整數呢?其實只需要對rand()函數生成的隨機數進行取模運算就可以了。參考下述代碼:
    int a = rand() % 100;
    int b = rand() % 20 + 5;
執行上述代碼后(當然前面應該調用srand函數),獲取的整數a是[0, 100)區間的均勻隨機整數;而獲取的整數b,則是[5, 25)區間的均勻隨機整數了。

但緊接着我們不禁要問了:隨機浮點數又該怎么生成呢?其實很簡單,用rand()生成的數除以RAND_MAX,不就能得到0~1之間的浮點數了么?而要得到區間[a, b]的浮點數,用這個值擴展一下不就好了?比如 s= rand() / RAND_MAX; s = a + (b-a)* s;這樣就能得到我們想要的隨機數s了。好的,假如我們要得到區間[3, 5]之間的一個隨機浮點數,那么很簡單,代碼如下: 
//代碼示例 start 
#include <stdio.h> 
#include <stdlib.h> 
#include <time.h> 

int main() 

    float s; 
    srand((int)time(0)); 
    s = (double)rand() / RAND_MAX; 
    s = 3 + (5-3) * s; 
    printf("%f\n", s); 

//代碼示例 end 
編譯運行,好吧。為什么每次程序運行得到的結果都是3.0呢?程序邏輯沒有問題的啊?! 
在倒數第三行設置斷點調試程序,我們會發現,在第一次完成對s的賦值之后,s的值為0.0。反復運行程序進行調試,s的值都是0.0。為什么s的值總是0.0呢? 
原來,在C語言中,如果 / 操作符兩邊都是整數的話,那么運算后的結果也是一個整數,而且是向下取整的整數。即2 / 3得到0,3 / 2得到1。又由於rand()得到的值總是小於RAND_MAX,因此表達式 rand() / RAND_MAX也就只能得到整數0了,整數0在賦值給s時強制轉換為浮點數0.0。 
為了讓 / 操作符進行浮點運算,我們可以將 / 操作符的操作數轉化為浮點數。比如:(float)rand() / RAND_MAX;這樣,就能得到我們想要的結果了。正確的例子如下: 
//代碼示例 start 
#include <stdio.h> 
#include <stdlib.h> 
#include <time.h> 

int main() 

    float s; 
    srand((int)time(0)); 
    s = (float)rand() / RAND_MAX; 
    s = 3 + (5-3) * s; 
    printf("%f\n", s); 

//代碼示例 end 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM