2012-09-13 25 views
2

我使用rand()作爲需要唯一值的6位字段。我做對了嗎?C中的rand()有多獨特?

什麼是賠率,rand()可以給我連續或頻繁的電話相似的價值?

當我使用rand()時它是唯一的。但是,當我撥打srand(time(NULL))srand(clock())時,返回相同的號碼。看起來,就像它對我來說正好相反。或者是?

+0

你應該只調用'srand'一次。這就是僞隨機數序列的種子。 – chris

+0

RAND_MAX需要15個「有效位」。在最糟糕的實現中,只有32K個不同的值。好消息是:現在大多數實現都比較好。 – wildplasser

+0

@wildplasser雖然合理的'rand()/ srand()'執行您的[評論](http://stackoverflow.com/questions/12412108/how-unique-is-rand-in-c/12412168#comment16682299_12412108),不幸的是,C沒有指定「只有(至少)32K個不同的值」,只有值的範圍 - 它們不需要全部發生。 – chux

回答

3

正如其他人所指出的那樣,唯一性並不能保證。但是,您可能會看到重複的數字,因爲您錯誤地使用了srand()和rand()。

srand()用於播種隨機數發生器。這意味着在調用srand之後對rand()的一系列調用將產生特定的一系列值。如果調用函數srand()使用相同的值,則RAND()會產生相同的一系列值(對於給定的實現,有不同的實現之間沒有擔保)對我來說這

int main() { 
    srand(100); 
    for(int i = 0; i<5; ++i) 
     printf("%d\n",rand()); 

    printf("\nreset\n\n"); 

    srand(100); 
    for(int i = 0; i<5; ++i) 
     printf("%d\n",rand()); 

} 

生產:

365 
1216 
5415 
16704 
24504 

reset 

365 
1216 
5415 
16704 
24504 

time()和clock()會返回時間,但是如果您足夠快地調用它們,則返回的值將相同,因此您將從rand()中獲得相同的一系列值。

此外,rand()通常不是一個非常好的隨機數生成器,使用它通常意味着您必須將一系列數字轉換爲您實際需要的分佈。你應該找到一種不同的隨機來源,要麼學習合適的方法來產生你想要的發行版,要麼使用一個可以爲你做的發行版。 (例如,生成0到N之間的「隨機」數字的一種常見方法是做rand() % N,但這並不是最好的方法。

C++在<random>中提供了一個好得多的隨機數字庫。它提供了不同的PRNG算法,如linear_congruential,mersennne_twister,甚至可能還有一個密碼安全的RNG(取決於實現)。它還提供用於生成各種分發的對象,例如uniform_int_distribution,它應避免rand() % N中出現的錯誤。

3

rand()返回0到RAND_MAX之間的值。由於它是一個分散的均勻分佈,因此重複數字的概率爲1 /(RAND_MAX +1),因此不保證唯一性。

srand(seed)初始化您的隨機數發生器,以便從rand()獲得號碼的順序是你每次seed初始化它給予相同的每一次。

在您的例子seed = time(NULL)其是從1月1日起經過的秒數,1970從而確保不同的種子,從而隨機數的不同的序列對每次調用srand(time(NULL))(假定它不是在相同的第二製造) 。

2

隨機數字是隨機,而不是唯一。就像擲骰子的情況一樣,當你連續擲出幾個六分球時,你的rand可以(也應該)有時會給你帶來相同的數字。

爲了確保數字是唯一的,請建立一個註冊已添加的每個數字的集合。當一個隨機數字出現不止一次時,扔第二個,然後去下一個。

0

什麼是賠率,蘭特()可以給我連續或頻繁的調用相似的值?

rand的算法是C.所以不確定是rand返回的數的隨機性質量。

enter image description here

+0

Downvoter,謹慎解釋你爲什麼downvoted? – ouah

+0

沒有幽默感(+1) – Jacob