關於rand和srand函式使用的一點心得

zs_find發表於2015-10-23

轉自:http://blog.csdn.net/lishuhuakai/article/details/8964852

 在c語言裡面,兩個函式包含在<stdlib.h>標頭檔案裡面,c++裡面,標準庫<cstdlib>(被包含於<iostream>中).

  srand函式是隨機數發生器的初始化函式。

        原型:void srand(unsigned seed);

        rand函式用來產生隨機數,當然是偽隨機數

       原型:int rand(void)

       seed的作用:srand函式的作用是根據引數seed,設定一個隨機起始點,而rand函式根據這個起始點,產生隨機數序列。預設的隨機種子為1。如果隨機種子一樣,rand函式所產生的隨機序列也一樣。
       
因此,為使每次程式執行都能產生不同的隨機序列,每次都應產生一個不同的種子引數


       說明

       因為rand的內部實現是用線性同餘法做的,它不是真的隨機數,只不過是因為其週期特別長,所以有一定的範圍裡可看成是隨機的,rand()會返回一隨機數值,範圍在0至RAND_MAX 間。在呼叫此函式產生隨機數前,必須先利用srand()設好隨機數種子,如果未設隨機數種子,rand()在呼叫時會自動設隨機數種子為1。rand()產生的是假隨機數字,每次執行時是相同的。若要不同,以不同的值來初始化它.初始化的函式就是srand()

      返回值:
      返回0至RAND_MAX之間的隨機整數值,RAND_MAX的範圍最少是在32767之間(int),即雙位元組(16位數)。若用unsigned int 雙位元組是65535,四位元組是4294967295的整數範圍。

       0~RAND_MAX每個數字被選中的機率是相同的。

       運用示例

  1. //取得0~6之間的隨機整數  
  2. #include <iostream>  
  3.   
  4. int main()  
  5. {  
  6.     for(int i=0;i<10;i++)  
  7.     {   
  8.         ran_num=rand()%6;  
  9.         cout<<ran_num<<" ";  
  10.     }  
  11.     return 0;  
  12. }  
  13. //由於種子預設都是1,故每次執行都將輸出:5 5 4 4 5 4 0 0 4 2   


     指定seed為定值1時:

  1. //取得0~6之間的隨機整數  
  2. #include <iostream>  
  3.   
  4. int main()  
  5. {  
  6.     srand(1);  
  7.     for(int i=0;i<10;i++)  
  8.     {   
  9.         ran_num=rand()%6;  
  10.         cout<<ran_num<<" ";  
  11.     }  
  12.     return 0;  
  13. }  
  14. //由於種子沒變化,每次執行都將輸出:5 5 4 4 5 4 0 0 4 2   

    指定seed為定值6:

  1. //取得0~6之間的隨機整數  
  2. #include <iostream>  
  3.   
  4. int main()  
  5. {  
  6.     srand(6);  
  7.     for(int i=0;i<10;i++)  
  8.     {   
  9.         ran_num=rand()%6;  
  10.         cout<<ran_num<<" ";  
  11.     }  
  12.     return 0;  
  13. }  
  14. //由於種子沒變化,每次執行都將輸出:每次執行都將輸出:4 1 5 1 4 3 4 4 2 2   

     那麼我們如何產生一個偽隨機的種子呢?一般指定seed為當前系統流逝了的時間(單位為秒):time_t time(0):

  1. //取得0~6之間的隨機整數  
  2. #include <iostream>  
  3. #include <ctime>//時間函式  
  4.   
  5. int main()  
  6. {  
  7.     srand((unsigned)time(0));  
  8.     for(int i=0;i<10;i++)  
  9.     {   
  10.         ran_num=rand()%6;  
  11.         cout<<ran_num<<" ";  
  12.     }  
  13.     return 0;  
  14. }  

            第一次執行時輸出: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。 

      另外還有一種比較常用的產生隨機種子的函式:

       srand(time(NULL)); //是以當前時間為種子,產生隨意數。其中,time(NULL)用來獲取當前時間,本質上得到的是一個大整數,然後用這個數來隨機數。


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

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


  1. #include <iostream>  
  2. #include <ctime>//時間函式  
  3.   
  4. int main()  
  5. {  
  6.     double ran_numf=0.0;  
  7.     srand((unsigned)time(0));  
  8.     for(int i=0;i<10;i++)  
  9.     {   
  10.         ran_numf = rand() / (double)(RAND_MAX);  
  11.         cout<<ran_numf<<" ";  
  12.     }  
  13.   
  14.     return 0;  
  15. }  
            執行結果為: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的情況,如此類推。 
       以上不是偽隨機浮點數最好的實現方法,不過可以將就著用用…


相關文章