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日零時零分零秒到目前爲止所通過的時間,單位爲秒。spa


好了,到目前爲止,咱們已經解決了如何在區間[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 
相關文章
相關標籤/搜索