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

发布于 2024-12-28 14:52:45 字数 819 浏览 0 评论 0原文

List::Gen< 中的 cartesian 函数/a> 似乎受到我的 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,subversion 3 (v5.12.3) 构建的 MSWin32-x64-multi-thread(有 9 个注册补丁,请参阅 perl -V 更多细节)

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

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 -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)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

北斗星光 2025-01-04 14:52:45

在某些时候,由于 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 位限制添加到下一个版本之前要进行的改进列表中。

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.

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.

椵侞 2025-01-04 14:52:45

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

List::Gen explicitly limits the result to 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
    };
    ...
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文