程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> 關於C語言 >> rand()和srand()產生偽隨機數的方法總結

rand()和srand()產生偽隨機數的方法總結

編輯:關於C語言
 

標准庫 <cstdlib> (被包含於 <iostream> 中)提供兩個幫助生成偽隨機數的函數:

 

函數一: int rand(void) ;

從 srand (seed) 中指定的 seed 開始,返回一個 [seed, RAND_MAX ( 0x7fff ) ) 間的隨機整數。

 

函數二: void srand(unsigned seed) ;

參數 seed 是 rand() 的種子,用來初始化 rand() 的起始值。

 

可以認為 rand() 在每次被調用的時候,它會查看:

1 ) 如果用戶在此之前調用過 srand(seed) ,給 seed 指定了一個值,那麼它會自動調用

srand(seed) 一次來初始化它的起始值。

2 ) 如果用戶在此之前沒有調用過 srand(seed) ,它會自動調用 srand(1) 一次。

 

根據上面的第一點我們可以得出:

1 ) 如果希望 rand ()在每次程序運行時產生的值都不一樣,必須給 srand(seed) 中的 seed 一個變值,這個變值必須在每次程序運行時都不一樣(比如到目前為止流逝的時間)。

2 ) 否則,如果給 seed 指定的是一個定值,那麼每次程序運行時 rand ()產生的值都會一樣,雖然這個值會是 [seed, RAND_MAX ( 0x7fff ) ) 之間的一個隨機取得的值。

3 ) 如果在調用 rand() 之前沒有調用過 srand(seed) ,效果將和調用了 srand(1) 再調用 rand() 一樣( 1 也是一個定值)。

 

舉幾個例子,假設我們要取得 0 ~ 6 之間的隨機整數(不含 6 本身):

 

例一,不指定 seed :

for(int i=0;i<10;i++){

ran_num=rand() % 6;

cout<<ran_num<<" ";

}

每次運行都將輸出: 5 5 4 4 5 4 0 0 4 2

 

例二,指定 seed 為定值 1 :

srand(1);

for(int i=0;i<10;i++){

ran_num=rand() % 6;

cout<<ran_num<<" ";

}

每次運行都將輸出: 5 5 4 4 5 4 0 0 4 2

跟例子一的結果完全一樣。

 

例三,指定 seed 為定值 6 :

srand(6);

for(int i=0;i<10;i++){

ran_num=rand() % 6;

cout<<ran_num<<" ";

}

每次運行都將輸出: 4 1 5 1 4 3 4 4 2 2

隨機值也是在 [0,6 )之間,隨得的值跟 srand(1) 不同,但是每次運行的結果都相同。

 

例四,指定 seed 為當前系統流逝了的時間(單位為秒): time_t time(0) :

#include <ctime>

//…

srand((unsigned)time(0));

for(int i=0;i<10;i++){

ran_num=rand() % 6;

cout<<ran_num<<" ";

}

第一次運行時輸出: 0 1 5 4 5 0 2 3 4 2

第二次: 3 2 3 0 3 5 5 2 2 3

總之,每次運行結果將不一樣,因為每次啟動程序的時刻都不同(間隔須大於 1 秒?見下)。

 

關於 time_t time(0) :

 

time_t 被定義為長整型,它返回從 1970 年 1 月 1 日 零時零分零秒到目前為止所經過的時間,單位為秒。比如假設輸出:

cout<<time(0);

值約為 1169174701 ,約等於 37 (年)乘 365 (天)乘 24 (小時)乘 3600 (秒)(月日沒算)。

 

另外,關於 ran_num = rand() % 6 ,

 

將 rand() 的返回值與 6 求模是必須的,這樣才能確保目的隨機數落在 [0,6) 之間,否則 rand() 的返回值本身可能是很巨大的。

一個通用的公式是:

要取得 [a,b) 之間的隨機整數,使用( rand() % (b-a) ) + a (結果值將含 a 不含 b )。

在 a 為 0 的情況下,簡寫為 rand() % b 。

 

最後,關於偽隨機浮點數:

 

用 rand() / double(RAND_MAX) 可以取得 0 ~ 1 之間的浮點數(注意,不同於整型時候的公式,是除以,不是求模),舉例:

double ran_numf=0.0;

srand((unsigned)time(0));

for(int i=0;i<10;i++){

ran_numf = rand() / (double)(RAND_MAX);

cout<<ran_numf<<" ";

}

運行結果為: 0.716636 , 0.457725 ,…等 10 個 0 ~ 1 之間的浮點數,每次結果都不同。

 

如果想取更大范圍的隨機浮點數,比如 1 ~ 10 ,可以將

rand() /(double)(RAND_MAX) 改為 rand() /(double)(RAND_MAX/10)

運行結果為: 7.19362 , 6.45775 ,…等 10 個 1 ~ 10 之間的浮點數,每次結果都不同。

至於 100 , 1000 的情況,如此類推。
 

 
  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved