2012-01-24 62 views
2

List::Gencartesian功能似乎是由32位無符號上限在我的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 [email protected]$combinations; # Should be 175**5 == 164_130_859_375 
         # prints -1+2**31 == 2_147_483_647 

有什麼辦法來克服這個限制?下面是我的Perl構建細節。

> perl -v 

這是 MSWin32-x64的多線程構建的perl 5,第12版,顛覆3(v5.12.3)(9個註冊補丁,看到的perl -V爲 更詳細)

+0

操作系統「位」並不重要。看起來這是一個64位版本的Perl,因此應該使用64位整數。請確認'perl -V:ivsize'是8. – ikegami

+0

@ikegami:'ivsize ='8';' – Zaid

+0

我在「cartesian」中得到「不是ARRAY參考」。它試圖array_deref「@ five_in_a_row」的內容。 – ikegami

回答

5

在某個點,該拴接口發電機將總是受到限制,由於到perl嵌合陣列indicies成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位限制的改進列表中的下一個版本之前進行。

+0

這可以工作。謝謝你一堆埃裏克。 – Zaid

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

奇怪。我的代碼現在返回922_102_127,比以前更小:/ – Zaid

相關問題