2011-09-14 75 views
1

下面是我用來練習使用rand()函數的示例程序。C編程 - rand()的奇怪輸出

最奇怪的是,每次運行程序時,rand()(程序輸出中的rand [0])生成的第一個數字都是SIMILAR。這是不一樣的,但數字總是比上一次生成時略大。蘭特[1-4]似乎是可以接受的隨機然而。任何人都可以解釋發生了什麼,爲什麼?

看看這個示例輸出:

[[email protected] C] $ ./a.out 
rand[0]= 277735441     <<<?????? 
rand[1]= 1417591956 
rand[2]= 1284424674 
rand[3]= 819876274 
rand[4]= 1405457966 
[[email protected] C] $ ./a.out 
rand[0]= 277769055     <<<??????? 
rand[1]= 1982542454 
rand[2]= 234757526 
rand[3]= 642279943 
rand[4]= 1546192179 
[[email protected] C] $ ./a.out 
rand[0]= 277785862     <<<??????? 
rand[1]= 117534056 
rand[2]= 1857407599 
rand[3]= 1627223601 
rand[4]= 542817462 

的源代碼:

/* 
    * rand: Generates 5 numbers using standard "srand()/rand()" function 
    * 
    * SAMPLE OUTPUT: 
    * rand[0]= 824522256 
    * rand[1]= 1360907941 
    * rand[2]= 1513675795 
    * rand[3]= 1046462087 
    * rand[4]= 253823980 
    */ 
    #include <stdio.h> 
    #include <stdlib.h> 
    #include <time.h> 

    int 
    main (int argc, char *argv[]) 
    { 
     /* Simple "srand()" seed: just use "time()" */ 
     unsigned int iseed = (unsigned int)time(0); 
     srand (iseed); 

     /* Now generate 5 pseudo-random numbers */ 
     int i; 
     for (i=0; i<5; i++) 
     { 
     printf ("rand[%d]= %u\n", 
      i, rand()); 
     } 
     return 0; 
    } 
+1

'蘭特'是相當糟糕和破碎。我的理解是,這是爲了一堂課或其他事情。如果有一天你真的需要使用僞隨機數,你應該嘗試找到另一個庫。 – zneak

回答

0

rand返回一個符號整數。您將其打印爲無符號值。

+1

但'rand'保證總是返回正整數,所以這不應該有任何區別。 – zneak

+0

如果我將它打印爲int,結果相同。 –

+0

,並沒有解釋每個的第一個結果的相似性。 – fvu

4

srand的常見實現使第一個隨機數與其種子高度相關。該標準不能保證序列必須是隨機的。

+0

在srand'之後做了一個'rand'? –

+0

所以在調用srand()之後,我應該拋出rand()生成的第一個數字。蘭特()應該工作這個......錯誤,很差?當然,我做錯了什麼。 –

+2

@yi_H(和@Albert),我認爲最好不要使用'rand'。該算法被廣泛認爲是蹩腳的。大多數平臺提供了更好的解決方案(如'隨機'函數,'/ dev/random'虛擬設備等),如果仍然找不到,那麼[Mersenne Twister](http://www.math .sci.hiroshima-u.ac.jp /〜m-mat/MT/emt.html)庫做得相當不錯。 – zneak

0

好吧,rand()是一個僞隨機生成器。由於您使用time()進行播種,這可能是數字相似的原因。

嘗試使用gettimeofday()乘以tv_sec * tv_usec或類似的東西進行種子播種。

0

僞隨機生成器從來沒有真正的隨機,但基於各種數學算法。在我的系統中,每個手冊頁使用的顯然是相當簡單的一個:

static unsigned long next = 1; 

    /* RAND_MAX assumed to be 32767 */ 
    int myrand(void) { 
    next = next * 1103515245 + 12345; 
     return((unsigned)(next/65536) % 32768); 
    } 

    void mysrand(unsigned seed) { 
     next = seed; 
    } 

這些類型的隨機發生器已經存在了一段時間。如果您熟悉餘數算術,那麼您會看到您獲得了一個初始值,然後扭曲並將餘下的餘數與32768相關,因此請在您的機器允許的範圍內獲得一個值。這個雖然是隨機的。所產生的價值將被用作下一個數字的起始值。

就你而言,你用當前時間種子。如果你足夠快地運行你的程序,你甚至可以得到相同的值(這不應該發生,但是當我編譯你的小程序並在我的系統上運行它時,它對我有用)。無論如何,如果你有一個跑得很快,你可能會看到類似的值 - 直到你翻轉餘下的基數。

可能閱讀了關於隨機數生成的位置:

http://en.wikipedia.org/wiki/Pseudorandom_number_generator

,它將使有點更有意義。

編輯:如果你想知道別人怎麼拿出來乘以你的種子值的常量,一個僞隨機生成的質量評估基於一些標準,比如,在所產生的價值「隨機找'或'聚集'。如果你需要認真的僞隨機數(可能不是現在),你可能想要實現你自己的。