剛好在找這方面的資料,看到了一片不錯的,就全文轉過來了,省的我以后再找找不到。
在C語言中,可以通過rand函數得到一個“偽隨機數”。這個數是一個整數,其值大於等於0且小於等於RAND_MAX。rand函數和常量RAND_MAX都定義在庫stdlib.h之中,這意味着必須在頭文件中包含庫stdlib.h才能使用rand函數和常量RAND_MAX。
rand函數聲明為:
int rand(void)
//代碼示例 start
#include <stdio.h>
#include <stdlib.h>
int main()
{
printf("%d %d\n", rand(), rand());
}
//代碼示例 end
編譯運行以上代碼,將在屏幕顯示兩個隨機數。但多次運行這個程序,你會發現每次程序啟動后生成的兩個隨機數都是一樣的!可見,rand()生成的值並不隨機。
標准庫(stdlib)中隨機數的一個可能的實現如下:
//代碼示例 start
#define RAND_MAX 0x7fff
unsigned long int next = 1;
int rand(void)
{
next = next * 1103515245 + 12345;
return (unsigned int)(next/65536) % RAND_MAX;
}
/*srand函數:為rand函數設置種子數*/
void srand(unsigned int seed)
{
next = seed;
}
//代碼示例 end
由上可知,只要我們每次在程序運行開始時用srand設置好不同的nex值,那么程序每次運行都將得到不同是隨機序列。那又如何給srand傳入不同的數呢?隨機數?好吧,這下變成雞生蛋蛋生雞的問題了。其實不用那么復雜。我們只需要把當前的時間作為srand的參數傳入就好了。程序每次運行的時間點是肯定是不一樣的。
要獲取當前時間,可以使用time庫中的time函數。示例如下:
//代碼示例 start
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main()
{
srand((int)time(0));
printf("%d %d\n", rand(), rand());
}
//代碼示例 end
編譯運行上述代碼,就能讓程序每次運行都得到不同的隨機值了。
程序中time(0)函數返回值類型為time_t(time_t定義為長整型),time(0)返回從1970年1月1日零時零分零秒到目前為止所經過的時間,單位為秒。
好了,到目前為止,我們已經解決了如何在區間[0, RAND_MAX]內等概率隨機獲得一個整數的問題。那么又應該如何等概率的隨機獲取任意范圍內的整數呢?其實只需要對rand()函數生成的隨機數進行取模運算就可以了。參考下述代碼:
int a = rand() % 100;
int b = rand() % 20 + 5;
執行上述代碼后(當然前面應該調用srand函數),獲取的整數a是[0, 100)區間的均勻隨機整數;而獲取的整數b,則是[5, 25)區間的均勻隨機整數了。
但緊接着我們不禁要問了:隨機浮點數又該怎么生成呢?其實很簡單,用rand()生成的數除以RAND_MAX,不就能得到0~1之間的浮點數了么?而要得到區間[a, b]的浮點數,用這個值擴展一下不就好了?比如 s= rand() / RAND_MAX; s = a + (b-a)* s;這樣就能得到我們想要的隨機數s了。好的,假如我們要得到區間[3, 5]之間的一個隨機浮點數,那么很簡單,代碼如下:
//代碼示例 start
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main()
{
float s;
srand((int)time(0));
s = (double)rand() / RAND_MAX;
s = 3 + (5-3) * s;
printf("%f\n", s);
}
//代碼示例 end
編譯運行,好吧。為什么每次程序運行得到的結果都是3.0呢?程序邏輯沒有問題的啊?!
在倒數第三行設置斷點調試程序,我們會發現,在第一次完成對s的賦值之后,s的值為0.0。反復運行程序進行調試,s的值都是0.0。為什么s的值總是0.0呢?
原來,在C語言中,如果 / 操作符兩邊都是整數的話,那么運算后的結果也是一個整數,而且是向下取整的整數。即2 / 3得到0,3 / 2得到1。又由於rand()得到的值總是小於RAND_MAX,因此表達式 rand() / RAND_MAX也就只能得到整數0了,整數0在賦值給s時強制轉換為浮點數0.0。
為了讓 / 操作符進行浮點運算,我們可以將 / 操作符的操作數轉化為浮點數。比如:(float)rand() / RAND_MAX;這樣,就能得到我們想要的結果了。正確的例子如下:
//代碼示例 start
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main()
{
float s;
srand((int)time(0));
s = (float)rand() / RAND_MAX;
s = 3 + (5-3) * s;
printf("%f\n", s);
}
//代碼示例 end