• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            lua的隨機數問題

            http://dev.csdn.net/author/yanjun_1982/b682d53ae78846a19eb0b7751a250750.html     

               也許很多人會奇怪為什么使用LUA的時候,第一個隨機數總是固定,而且常常是最小的那個值,下面我就簡要的說明一下吧,說得不好,還請諒解。我現在使用的4.0版本的LUA,看的代碼是5.0的,呵呵

                    LUA4.0版本中的自帶函數庫中有兩個關于隨機數的函數,一個是random,一個是randomseed。random有兩個參數,用來設置隨機數的范圍,比如random(1,100)設置隨機數的范圍為1至100之間。由于C中所產生的隨機序列是固定的,并且第一個隨機數比較小,只有41。LUA重新設計了random函數,使得它可以產生范圍固定的隨機數,但由于LUA的random只是封裝了C的rand函數,使得random函數也有一定的缺陷,那就是如果random的兩個輸入參數的值相差很小的時候,那么隨機序列的第一個隨機數就會和第一個輸入參數很接近,比如第一次調用random(1,100)的時候,返回值肯定是1,只有相差大于799時,如random(1,800)第一次調用才會返回2,也是很接近1。
                    由于這個原因,為了實現真正的隨機,那么第一次就不能讓玩家調用random函數,不然玩家就可以獲得一些低概率的東西了。比如if random(1,100) == 1 then ...... do,看起來是1%的的概率,但是第一次執行的時候是100%成立的,存在一定的隱患。解決這個問題的方法有兩個,一就是第一次random函數不能讓玩家執行,二就是使用randomseed先設一個隨機種子。對于第一種方法,可能還是有一定的風險,畢竟隨機序列還是固定的,玩家第一次調用random的時候還是得到有規律的返回值。第二種方法比較安全,在服務器啟動的時候設置一個隨機種子,讓系統產生的隨機序列不相同,但使用randomseed的時候也還要注意一個問題,那就是做種子的數要足夠的大,大于10000就行了。不然randomseed所產生的隨機序列的第一個值還是很小。原因是randomseed是直接封裝了C的srand,如果種子的值太小,那么srand所產生的序列和默認序列(srand(1)所產生的序列)是相差不大的,序列的第一個值還是很小。
                    因此,只要在服務器啟動的時候調用一下randomseed(GetTime())就可以解決這個問題了。
                    還要補充一下,LUA中產生隨機數的算法還是有一些問題,比如執行random(1,3276700),它返回的值最后兩位必為0。這是由LUA本身的隨機函數算法決定的。
                    還是簡要介紹一下LUA中random函數的實現方法吧,主要由源碼中的下面兩行實現:
                    lua_Number r = (lua_Number)(rand()%RAND_MAX) / (lua_Number)RAND_MAX;
                    lua_pushnumber(L, (int)floor(r*(u-m+1))+m);
                    其中m為random函數的第一個參數,u為第二個參數。由上面的代碼可以看出,如果u-l太小,那么當r也很小的時候,r*(u-m+1)就會很小(小于1),那么再經過floor運算,最經結果就是m。這就可以解釋為什么random產生的第一個隨機數常常會很接近m。再來看看當m為0,u為327670的時候會怎樣。在上面的代碼里,RAND_MAX是一個宏,它的值是32767,也就是C語言中rand函數可以返回的最大值(不同的操作系統可能會有不一樣的最大值)。當m為0,u為327670的時候,那么返回值就是floor(r*(327671)+0),我們再假設LUA與平臺無關并且rand不會返回32767(上面用%避免了這個問題),那么r就可以簡化為rand()/RAND_MAX,代入上式為floor(rand()*327671/32767)+0,就算rand()的返回值是32766,最終的結果也只有327660.99996......,經過floor運算后,最后那位數必為0。呵呵,我叫這樣的隨機數就偽隨機數中的偽隨機數。實際上面的公式是不允許化簡的,即不能簡單地把r代入r*(u-m+1),至于為什么,呵呵,因為r的值并不是rand()/RAND_MAX的值,r是double類型的,所以它只是一個和rand()/RAND_MAX很接近的數。 

                    引用請注明出處。作者:yanjun_1982   日期:2006年10月11日

            posted on 2009-05-13 10:58 Brandon 閱讀(2085) 評論(0)  編輯 收藏 引用 所屬分類: 腳本語言

            <2009年4月>
            2930311234
            567891011
            12131415161718
            19202122232425
            262728293012
            3456789

            導航

            統計

            常用鏈接

            留言簿(2)

            隨筆分類

            隨筆檔案

            文章分類

            文章檔案

            收藏夾

            IT WEB

            常用鏈接

            牛人BLOG

            學習網站

            搜索

            積分與排名

            最新評論

            閱讀排行榜

            評論排行榜

            国产精品9999久久久久| 国产福利电影一区二区三区久久老子无码午夜伦不 | 国产69精品久久久久9999APGF | 亚洲国产精品一区二区三区久久| 久久影视综合亚洲| 天天爽天天狠久久久综合麻豆| 久久精品国产亚洲AV无码偷窥| 久久精品国产91久久综合麻豆自制 | 久久综合中文字幕| 久久九九久精品国产免费直播| 久久亚洲精品成人无码网站 | 中文字幕亚洲综合久久菠萝蜜| 亚洲午夜久久久久妓女影院| 日韩精品国产自在久久现线拍| 国产成人综合久久精品红| 久久精品aⅴ无码中文字字幕重口| 大蕉久久伊人中文字幕| 久久久久久国产a免费观看黄色大片 | 精品久久久久久国产| 久久精品国产亚洲AV蜜臀色欲 | 青青青国产精品国产精品久久久久| 欧美一级久久久久久久大片| 久久久久久久波多野结衣高潮| 狠狠综合久久综合88亚洲| 久久综合久久综合九色| 日韩AV无码久久一区二区| 性做久久久久久久久久久| 天天爽天天爽天天片a久久网| 久久国产劲爆AV内射—百度| 国产亚洲色婷婷久久99精品91| 国产成年无码久久久久毛片| 欧美日韩精品久久久久| 少妇久久久久久被弄到高潮 | 久久久噜噜噜久久熟女AA片| 久久人人爽人人爽人人片AV不| 久久久久国产精品麻豆AR影院| 国产精品免费久久久久影院| 青青国产成人久久91网| 色综合久久综合网观看| 国内精品免费久久影院| 九九久久精品国产|