2011-05-13 31 views
5

rand(n)返回0n之間的數字。將rand按預期工作,關於「隨機性」,對於我的平臺上的整數限制的所有參數?Perl的rand的參數有多大?

+2

更多信息,我發現這個有趣:http://wellington.pm.org/archive/200704/randomness/index.html – vol7ron 2011-05-13 14:52:03

回答

8

這將取決於你的randbits值:

蘭特呼叫您的系統的隨機數發生器(或任何一個被 編譯到你的Perl的複印件)。在本次討論中,我將調用發生器RAND 將它與rand,rand的函數區分開來。蘭德產生 一個從0到2的整數** randbits - 1(含1),其中randbits是一個整數小的 整數。要查看它在perl中的含義,請使用命令'perl -V:randbits'。常用值爲15,16或31.

當您使用參數arg調用rand時,perl將該值作爲 整數並計算該值。

     arg * RAND 
      rand(arg) = --------------- 
         2**randbits 

該值將始終落在要求的範圍內。

  0 <= rand(arg) < arg 

但隨着ARG相比變大到2 ** randbits,事情變得 問題。讓我們想象一下randbits = 15的機器,所以RAND的範圍從0到32767不等,爲 。也就是說,無論何時我們調用RAND,我們都會得到32768 個可能的值之一。因此,當我們調用rand(arg)時,我們得到可能的值之一32768。

+1

要訪問perl內的randbits,'使用配置;打印$ Config :: Config {'randbits'}'。 MSWin32的randbits爲15,大多數其他平臺的爲48。 – ysth 2011-05-13 17:19:26

+1

@ysth還有perl -V:randbits – 2011-05-13 17:20:31

+1

是的,這是在答案中提到的,但從perl內使用它會有點愚蠢...... – ysth 2011-05-13 17:30:49

2

它取決於系統(僞)隨機數發生器使用的位數。您可以通過

use Config; 
my $randbits = $Config{randbits}; 

rand發現通過

perl -V:randbits 

或程序中的這個值可以產生2^randbits不同的隨機數。雖然可以生成大於2^randbits的數字,但當N> 2^randbits時,無法生成範圍[0,N)中的所有整數值。

由於(整數截尾)隨機值的分佈不會很平坦,因此N的值不是2的冪也是有問題的。有些價值觀略有過度表現,有些則略低。

值得注意的是,randbits在Windows上是微不足道的15。這意味着你只能得到32768(2 ** 15)不同的值。您可以通過多次調用rand以及組合所述值改善情況:

use Config; 
use constant RANDBITS => $Config{randbits}; 
use constant RAND_MAX => 2**RANDBITS; 

sub double_rand { 
    my $max = shift || 1; 
    my $iv = 
      int rand(RAND_MAX) << RANDBITS 
     | int rand(RAND_MAX); 
    return $max * ($iv/2**(2*RANDBITS)); 
} 

假設randbits = 15,double_rand模仿randbits = 30,提供1073741824(2 ** 30)可能的不同的值。這減輕了(但不能消除)上述兩個問題。

0

我們在談論大隨機整數以及是否有可能獲得它們。應該指出,兩個隨機整數的連接也是一個隨機整數。所以,如果你的系統,以任何理由,都無法超越999999999999,然後只寫

$bigrand = int(rand(999999999999)).int(rand(999999999999)); 

,你會得到(最大)的兩倍長度的隨機整數。

(其實這不是一個數字問題的回答「一蘭特數量有多大」,而是回答「你可以得到你想要的,只是串聯小的數字爲大」。)

+3

歡迎使用Stack Overflow。兩個現有答案中的一個答案涵蓋了你所建議的答案,並且答案覆蓋得更好。如果你打算使用你的技術,你需要確保數字的第二部分前綴足夠的零。您在示例中選擇了12位數字,這可能會導致一些問題; 9位數字會更安全。您可能需要使用'sprintf(「%d%09d」,rand(999_999_999),rand(999_999_999))'來生成字符串。即使這可能在Windows上有問題;查看其他答案爲什麼。 – 2012-09-22 19:25:36