標准庫 <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 的情況,如此類推。