2015年1月29日 星期四

C++ 亂數函數 rand() 和 srand()




所謂的亂數,即是指電腦自動產生的一個數字,好似一個六合彩號碼般,
無永遠沒法知道下一個出現的號碼。而C/C++的亂碼其實是由一個亂數產
生器產生的,函數名稱是rand,放在stdlib.h / cstdlib 表頭檔裡面,在使用
時直接呼叫 rand() 便可。


註:若果你不明白表頭檔 <stdlib.h> 是什麼 ,可以到這篇文章看看-->> stdlib.h介紹





Rand() 和 Srand()



先來個rand()使用的示範:
==================================

  1. #include <iostream>
  2. #include <stdlib.h>    // 引入表頭檔

  3. using namespace std;  

  4. int main(){

  5.     for(int i=0; i<5; i++){
  6.         cout<< rand() << endl;    // 印出5個亂數
  7.     }
  8.  
  9.     return 0;
  10.    


===================================



你可能會好奇,那究竟這些亂數的範圍到底是多少呢?

目前可以確定的是,最大值(RAND_MAX) 至少會是 0x7fff (轉換10進制後是32767),
最大會是多少不一定。以 Visual C++ 2010 環境而言,這個值是 32767。實際上
VC6.0 , VC2002 / 2003 , VC2008, VC2010 , gcc, Dev-C++ , Code::Blocks (with mingw) ,
這個值也都剛好是 32767,只是他們實作的亂數細節不同而已。但新版的版本的
RAND_MAX 會更大,例如在mac上用xcode開發的C/C++,最大值便是2147483647(231-1)
主要是看軟體( compiler )的實作方式,若想查下最大值是多少,不坊用以下程式測試一下:



========================
  1. #include <iostream>
  2. #include <stdlib.h>
  3. using namespace std;
  4. int main(){
  5.  
  6.     cout<< RAND_MAX;
  7.  
  8.     return 0;
  9.    
  10. }
========================


另外,當你不停用rand() run最初的程式時,會發現產生出來的亂數都是一樣的,因為rand()產生
的是偽隨機數字,每次執行時都是相同的,給果想要不同,就要使用srand()函數初始化它。

在預設的情況下,rand()的隨機種子(seed :指起始點,即最小值) 是1,而相同的隨機種子
產生的結果都是一樣的。那初始值該給多少?初始值給固定的值都沒用,要會隨著環境變動
的值才有意義,像是 記憶體使用量、process id 、CPU 使用率 等,這些都是會隨環境變動,
但有些變動性可能不大,而最常用來給初始值的,是時間,所以程式可以修改如下:


===========================================

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <time.h>
  4. int main()
  5. {
  6.     int i;
  7.     unsigned seed;
  8.     seed = (unsigned)time(NULL); // 取得時間序列
  9.     srand(seed); // 以時間序列當亂數種子
  10.     for(i=0; i<5; i++)
  11.          cout << rand() << endl; 
  12.     return 0;
  13. }

===========================================


註:

- 7-9 行可以縮短為 srand( (unsigned) time(NULL) );

- time(NULL),傳入值為NULL可以獲取當前時間的總秒數(從 00:00 hours, Jan 1, 1970 UTC 起),
  實際語法如下, time_t time (time_t* timer) 。

- 如果不明白什麼是 unsigned ,請先看這篇文章--> Unsigned keyword







Rand() 指定範圍



-需要使用%運算子,如果不明什麼是%,就GOOGLE一下吧。

程式如下:

================================

  1. #include <iostream>
  2. #include <stdlib.h>
  3. #include <time.h>

  4. using namespace std;


  5. int main(){

  6.     srand( (int)time(NULL));
  7.  
  8.     for(int i=0; i<5; i++)
  9.     cout<< rand()%6+2 <<endl;
  10.  
  11.     return 0;
  12.    
  13. }

================================


以上程序運行後,將會輸出5個號碼,範圍由 2~7 。

-rand()%6 :即指定範圍需要由起始數開始取6個數值,包括起始數
-rand()%6+2 :+2 的意思是指定起始數是2,然後由2開始取六個數作為range(包括2),
                           若沒有+2,起始數預設是0。










4 則留言:

  1. #include
    #include
    #include
    int main()
    {
    int i;
    unsigned seed;
    seed = (unsigned)time(NULL); // 取得時間序列
    srand(seed); // 以時間序列當亂數種子
    for(i=0; i<5; i++)
    count << rand() << endl;
    return 0;
    }


    count(?)應該是cout吧??

    回覆刪除
  2. #include
    #include
    #include
    int main()
    {
    int i;
    unsigned seed;
    seed = (unsigned)time(NULL); // ??????
    srand(seed); // ??????????
    for(i=0; i<5; i++)
    cout << rand() << endl; 這行無法執行也!
    return 0;
    }
    顯示cout was not declared in this scope
    end1也是

    回覆刪除
    回覆
    1. 要加
      using namespace std;
      或是
      using std::cout;
      using std::endl;

      刪除