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

时间:2022-09-06 22:17:39

The cartesian function inside List::Gen seems to be limited by the unsigned 32-bit upper limit on my 64-bit Windows OS:

List :: Gen中的笛卡尔函数似乎受到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

Is there any way to overcome this limitation? My Perl build details are below.

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

> perl -v

This is perl 5, version 12, subversion 3 (v5.12.3) built for MSWin32-x64-multi-thread (with 9 registered patches, see perl -V for more detail)

这是为MSWin32-x64多线程构建的perl 5,版本12,subversion 3(v5.12.3)(有9个已注册的补丁,有关详细信息,请参阅perl -V)

2 个解决方案

#1


5  

At some point, the tied interface to generators will always be limited, due to perl fitting array indicies into 32 or 64 bit integers. Beyond that range, you can use the object oriented interface to generators, which is not limited to 2**31-1 and is much faster than then tied interface.

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

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

say $combinations->size; # 164130859375

and to get an element:

并获得一个元素:

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

or

要么

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

And I will add auto-detected 64-bit limits to the list of improvements to make before the next release.

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

#2


2  

List::Gen explicitly limits the result to 2**31-1.

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

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

You could change it to

你可以改成它

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
    };
    ...
}

#1


5  

At some point, the tied interface to generators will always be limited, due to perl fitting array indicies into 32 or 64 bit integers. Beyond that range, you can use the object oriented interface to generators, which is not limited to 2**31-1 and is much faster than then tied interface.

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

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

say $combinations->size; # 164130859375

and to get an element:

并获得一个元素:

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

or

要么

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

And I will add auto-detected 64-bit limits to the list of improvements to make before the next release.

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

#2


2  

List::Gen explicitly limits the result to 2**31-1.

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

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

You could change it to

你可以改成它

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
    };
    ...
}