Perl's rand的争论有多大?

时间:2011-05-13 14:31:24

标签: perl random

rand(n)会返回0n之间的数字。对于“随机性”,rand是否会按预期工作,对于我平台上的整数限制的所有参数?

3 个答案:

答案 0 :(得分:8)

这取决于您的randbits值:

  

rand调用系统的随机数生成器(或者任何一个)      编译成你的Perl副本)。对于这个讨论,我会称之为      生成器RAND将它与rand,Perl的功能区分开来。兰德生产      一个从0到2的整数** randbits - 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的机器,所以兰德范围      从0..32767。也就是说,无论何时我们称之为RAND,我们都会获得32768中的一个      可能的价值观因此,当我们调用rand(arg)时,我们得到32768之一      可能的价值观。

答案 1 :(得分:2)

它取决于系统(伪)随机数生成器使用的位数。您可以通过

找到此值
perl -V:randbits

或在程序中通过

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

rand可以生成2 ^ randbits不同的随机数。虽然您可以生成大于2 ^ randbits的数字,但是当N&gt;时,您无法生成[0,N]范围内的所有整数值。 2 ^ randbits。

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)个可能的不同值。这减轻了(但永远不会消除)上述两个问题。

答案 2 :(得分:0)

我们正在谈论大的随机整数以及是否有可能得到它们。应该注意,两个随机整数的串联也是随机整数。因此,如果您的系统因任何原因无法超越999999999999,那么只需编写

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

你会得到两倍于(最大)长度的随机整数。

(实际上,这不是“兰特数量有多大”这个问题的数字答案,而是答案“你可以得到你想要的那么大,只需连接小数字”。)