本文分享了C語言/C++如何產生隨機數的具體實現方法,供大家參考,具體內容如下
C語言/C++怎樣產生隨機數:這裡要用到的是rand()函數, srand()函數,C語言/C++裡沒有內建的random(int number)函數。
(1) 如果你只要產生隨機數而不需要定義範圍的話,你只要用rand()就可以了:rand()會返回一隨機數值, 範圍在0至RAND_MAX 間。RAND_MAX定義在stdlib.h, 其值為2147483647。
例如:
#include<stdio.h>#include<stdlib.h>void main(){ for(int i=0;i<10;i+) printf("%d\n",rand());}
(2) 如果你要隨機產生一個在一定範圍的數,你可以在宏定義中定義一個random(int number)函數,然後在main()裡面直接調用random()函數:
例如:隨機產生10個0~100的數:
#include<stdio.h>#include<stdlib.h>#define random(x) (rand()%x)void main(){ for(int x=0;x<10;x++) printf("%d\n",random(100));}
(3)但是上面兩個例子所產生的隨機數都只能是 一次性的,如果你第二次啟動並執行時候輸出結果仍和第一次一樣。這與srand()函數有關。srand()用來設定rand()產生隨機數時的隨機數種子。 在調用rand()函數產生隨機數前,必須先利用srand()設好隨機數種子(seed), 如果未設隨機數種子, rand()在調用時會自動設隨機數種子為1。上面的兩個例子就是因為沒有設定隨機數種子,每次隨機數種子都自動設成相同值1 ,進而導致rand()所產生的隨機數值都一樣。
srand()函數定義 : void srand (unsigned int seed);
通常可以利用geypid()或time(0)的傳回值來當做seed
如果你用time(0)的話,要加入標頭檔#include<time.h>
例如:
#include<stdio.h>#include<stdlib.h>#include<time.h>#define random(x) (rand()%x)void main(){ srand((int)time(0)); for(int x=0;x<10;x++) printf("%d\n",random(100));}
隨機數在實際運用中非常之多,如遊戲設計,訊號處理,通常我們很容易得到平均分布的隨機數。但如何根據平均分布的隨機數進而產生其它分布的隨機數呢?本文提出了一種基於幾何直觀面積的方法,以常態分佈隨機數的產生為例討論了任意分布的隨機數的產生方法。
一、平均分布隨機數的產生
大家都知道,隨機數在各個方面都有很大的作用,在vc的環境下,為我們提供了庫函數rand()來產生一個隨機的整數。該隨機數是平均在0~RAND_MAX之間平均分布的,RAND_MAX是一個常量,在VC6.0環境下是這樣定義的:
#define RAND_MAX 0x7fff
它是一個short 型資料的最大值,如果要產生一個浮點型的隨機數,可以將rand()/1000.0這樣就得到一個0~32.767之間平均分布的隨機浮點數。如果要使得 範圍大一點,那麼可以通過產生幾個隨機數的線性組合來實現任意範圍內的平均分布的隨機數。例如要產生-1000~1000之間的精度為四位小數的平均分布 的隨機數可以這樣來實現。先產生一個0到10000之間的隨機整數。方法如下 :
int a = rand()000;
然後保留四位小數產生0~1之間的隨機小數:
double b = (double)a/10000.0;
然後通過線性組合就可以實現任意範圍內的隨機數的產生,要實現-1000~1000內的平均分布的隨機數可以這樣做:
double dValue = (rand()000)/10000.0*1000-(rand()000)/10000.0*1000;
則dValue就是所要的值。
到現在為止,你或許以為一切工作都已經完成了,其實不然,仔細一看,你會發現有問題的,上面的式子化簡後就變為:
double dValue = (rand()000)/10.0-(rand()000)/10.0;
這樣一來,產生的隨機數範圍是正確的,但是精度不正確了,變成了只有一位正確的小數的隨機數了,後面三位的小數都是零,顯然不是我們要求的,什麼原因呢,又怎麼辦呢。
先找原因,rand()產生的隨機數解析度為32767,兩個就是65534,而經過求餘後分辨度還要減小為10000,兩個就是20000而要求的解析度為1000*10000*2=20000000,顯然遠遠不夠。下面提供的方法可以實現正確的結果:
double a = (rand()000) * (rand()00)/10000.0;double b = (rand()000) * (rand()00)/10000.0;double dValue = a-b;
則dValue就是所要求的結果。在下面的函數中可以實現產生一個在一個區間之內的平均分布的隨機數,精度是4位小數。
double AverageRandom(double min,double max){int minInteger = (int)(min*10000);int maxInteger = (int)(max*10000);int randInteger = rand()*rand();int diffInteger = maxInteger - minInteger;int resultInteger = randInteger % diffInteger + minInteger;return resultInteger/10000.0;}
但是有一個值得注意的問題,隨機數的產生需要有一個隨機的種子,因為用電腦產生的隨機數是通過遞推的方法得來的,必須有一個初始值,也就是通常所說的隨 機種子,如果不對隨機種子進行初始化,那麼電腦有一個確省的隨機種子,這樣每次遞推的結果就完全相同了,因此需要在每次程式運行時對隨機種子進行初始 化,在vc中的方法是調用srand(int)這個函數,其參數就是隨機種子,但是如果給一個常量,則得到的隨機序列就完全相同了,因此可以使用系統的時 間來作為隨機種子,因為系統時間可以保證它的隨機性。
調用方法是srand(GetTickCount()),但是又不能在每次調用rand()的時候都用srand(GetTickCount())來初始 化,因為現在電腦已耗用時間比較快,當連續調用rand()時,系統的時間還沒有更新,所以得到的隨機種子在一段時間內是完全相同的,因此一般只在進行一 次大批隨機數產生之前進行一次隨機種子的初始化。下面的代碼產生了400個在-1~1之間的平均分布的隨機數。
double dValue[400];srand(GetTickCount());for(int i= 0;i < 400; i++){double dValue[i] = AverageRandom(-1,1);}
以上就是本文的全部內容,希望對大家的學習有所協助。