是否有可能克服这种32位限制?

时间:2012-01-24 06:04:42

标签: perl 32bit-64bit

List::Gen内的cartesian函数似乎受到64位Windows操作系统上无符号32位上限的限制:

use strict;
use warnings;
use List::Gen '*';
use 5.010;
use bigint;               # This didn't help either

say $List::Gen::VERSION;  # 0.80

my $diameters = range( 1, 175 );
my @five_in_a_row = ( $diameters ) x 5;

my $combinations = cartesian { \@_ } @five_in_a_row;

say 0+@$combinations;   # Should be 175**5 == 164_130_859_375
                        # prints -1+2**31  ==   2_147_483_647

有没有办法克服这个限制?我的Perl构建细节如下。

> perl -v
     

这是perl 5,版本12,颠覆3(v5.12.3)   MSWin32-x64多线程(有9个注册补丁,请参阅perl -V for   更多细节)

2 个答案:

答案 0 :(得分:5)

在某些时候,由于perl拟合数组指示为32或64位整数,因此生成器的绑定接口将始终受到限制。超出该范围,您可以使用面向对象的生成器接口,不仅限于2**31-1,并且比绑定接口快得多。

my $combinations = cartesian {\@_} map {range 1 => 175} 1 .. 5;

say $combinations->size; # 164130859375

并获得一个元素:

my $x = $combinations->get(164130859374);

my $x = $combinations->(164130859374);

我将在下一个版本发布之前将自动检测到的64位限制添加到要进行的改进列表中。

答案 1 :(得分:2)

List :: Gen明确地将结果限制为2 ** 31-1。

sub FETCHSIZE {
    ...
    my $fetchsize = sub {
        my $size  = $realsize->();
        $size > 2**31-1
              ? 2**31-1
              : $size
    };
    ...
}

您可以将其更改为

use Config qw( );
my $max_iv = $Config::Config{ivsize} == 8 ? 2**63-1 : 2**31-1;

sub FETCHSIZE {
    ...
    my $fetchsize = sub {
        my $size  = $realsize->();
        $size > $max_iv
              ? $max_iv
              : $size
    };
    ...
}