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 更多细节)
答案 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
};
...
}