• <ruby id="5koa6"></ruby>
    <ruby id="5koa6"><option id="5koa6"><thead id="5koa6"></thead></option></ruby>

    <progress id="5koa6"></progress>

  • <strong id="5koa6"></strong>
  • 菜鳥問與答(怎樣產生隨機數)

    發表于:2007-07-14來源:作者:點擊數: 標簽:
    菜鳥問與答(怎樣產生隨機數): 問:怎樣產生隨機數? 答: 在計算機中并沒有一個真正的隨機數發生器,但是可以做到使產生的數字重復率很低,這樣看起來好象是真正的隨機數,實現這一功能的程序叫偽隨機數發生器。 有關如何產生隨機數的理論有許多,如果要詳
    菜鳥問與答(怎樣產生隨機數):

    問:怎樣產生隨機數?

    答:    在計算機中并沒有一個真正的隨機數發生器,但是可以做到使產生的數字重復率很低,這樣看起來好象是真正的隨機數,實現這一功能的程序叫偽隨機數發生器。
        有關如何產生隨機數的理論有許多,如果要詳細地討論,需要厚厚的一本書的篇幅。不管用什么方法實現隨機數發生器,都必須給它提供一個名為“種子”的初始值。而且這個值最好是隨機的,或者至少這個值是偽隨機的?!胺N子”的值通常是用快速計數寄存器或移位寄存器來生成的。
       下面講一講在C語言里所提供的隨機數發生器的用法?,F在的C編譯器都提供了一個基于ANSI標準的偽隨機數發生器函數,用來生成隨機數。它們就是rand()和srand()函數。這二個函數的工作過程如下:
    1) 首先給srand()提供一個種子,它是一個unsigned int類型,其取值范圍從0~65535;
    2) 然后調用rand(),它會根據提供給srand()的種子值返回一個隨機數(在0到32767之間)
    3) 根據需要多次調用rand(),從而不間斷地得到新的隨機數;
    4) 無論什么時候,都可以給srand()提供一個新的種子,從而進一步“隨機化”rand()的輸出結果。

        這個過程看起來很簡單,問題是如果你每次調用srand()時都提供相同的種子值,那么,你將會得到相同的隨機數序列,這時看到的現象是沒有隨機數,而每一次的數都是一樣的了。例如,在以17為種子值調用srand()之后,在首次調用rand()時,得到隨機數94。在第二次和第三次調用rand()時將分別得到26602和30017,這些數看上去是很隨機的(盡管這只是一個很小的數據點集合),但是,在你再次以17為種子值調用srand()后,在對于rand()的前三次調用中,所得的返回值仍然是在對94,26602,30017,并且此后得到的返回值仍然是在對rand()的第一批調用中所得到的其余的返回值。因此只有再次給srand()提供一個隨機的種子值,才能再次得到一個隨機數。
        下面的例子用一種簡單而有效的方法來產生一個相當隨機的“種子”值----當天的時間值:
    #include<stdio.h>
    #include<stdlib.h>
    #include<sys/types.h>
    #include<sys/timeb.h>

    void main(void)
    {
        int i;
        unsigned int seedVal;
        struct timeb timeBuf;
        ftime(&timeBuf);
        seedVal=((((unsigned int)timeBuf.time&0xFFFF)+
                     (unsigned int)timeBuf.millitm)^
                     (unsigned int)timeBuf.millitm);
        srand((unsigned int)seedVal);
        for(i=0;i<10;++i)
            printf("%6d\n",rand());
    }
    上面的程序先是調用_ftime()來檢查當前時間,并把它的值存入結構成員timeBuf.time中,當前時間的值從1970年1月1日開始以秒計算。在調用了_ftime()之后,在結構timeBuf的成員millitm中還存入了當前那一秒已經度過的毫秒數,但在DOS中這個數字實際上是以百分之一秒來計算的。然后,把毫秒數和秒數相加,再和毫秒數進行異或運算。當然也可以對這兩個結構成員進行更多的計算,以控制seedVal的取值范圍,并進一步加強它的隨機性,但上例用的邏輯運算就已經足夠了。
        注意上例中rand()的輸出并沒有被限制在一個指定的范圍,假定要建立一個彩票選號器,其取值范圍是從1到44??梢院唵蔚睾雎缘魊and()所輸出的在該范圍外的值,但這將花費許多時間去得到所需的全部(例如6個)彩票號碼。假如你已經建立了一個隨機數發生器,它所產生的隨機數范圍是從0到32767,而你想把輸出限制在1到44之間。下面的例子就說明了如何來完成這項工作:
    int i,k range;
    int min,max;
    double j;

    min=1;
    max=44;
    range=max-min;
    i=rand();

    j=((oduble)i/(double)RAND_MAX);

    i=(int)(j*(double)range);
    i+=min;

    這個例子把輸出的隨機數限制在1到44之間,其工作原理如下:
    1)得到一個在0到RAND_MAX(32767)之間的隨機數,把它除以RAND_MAX,從而產生一個在0到1之間的校正值;
    2)把校正值乘以所需要的范圍值(在本例中為43,即44-1)從而產生一個在0到43之間的值
    3) 把該值和所要求的最小值相加,從而使該值最終落在正確的取值范圍----1到44之間。你可以用不同的min和max值來驗證這個例子,你會發現它總是會正確地產生在新的min和max值之間的隨機數。

    原文轉自:http://www.kjueaiud.com

    老湿亚洲永久精品ww47香蕉图片_日韩欧美中文字幕北美法律_国产AV永久无码天堂影院_久久婷婷综合色丁香五月

  • <ruby id="5koa6"></ruby>
    <ruby id="5koa6"><option id="5koa6"><thead id="5koa6"></thead></option></ruby>

    <progress id="5koa6"></progress>

  • <strong id="5koa6"></strong>