關於LUA中的隨機數問題

2022-09-17 03:36:10 字數 1850 閱讀 1435

也許很多人會奇怪為什麼使用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很接近的數。 

關於LUA中的隨機數問題

也許很多人會奇怪為什麼使用lua的時候,第乙個隨機數總是固定,而且常常是最小的那個值,下面我就簡要的說明一下吧,說得不好,還請諒解。我現在使用的4.0版本的lua,看的 是5.0的,呵呵 lua4.0版本中的自帶函式庫中有兩個關於隨機數的函式,乙個是random,乙個是randomseed。rand...

lua 中隨機數產生

需要用到兩個函式 1 math.randomseed n 接收乙個整數n作為隨機序列種子 2 math.random n,m 這個函式有三種用法,分別是不跟引數,此時產生 0,1 之間的隨機浮點數 有乙個引數n,產生1到n之間的整數 有2個引數n和m,產生n到m之間的隨機整數。最常用的方法是 mat...

Lua 隨機數生成問題

lua 生成隨機數需要用到兩個函式 math.randomseed xx math.random n m 1.math.randomseed n 接收乙個整數 n 作為隨機序列種子。2.math.random n m 有三種用法 無參呼叫,產生 0,1 之間的浮點隨機數 只有引數 n,產生 1 n ...