Re: big integers forcing me to be a C programmer: "range iterator outside integer range"
by ikegami (Patriarch) on May 07, 2009 at 10:47 UTC
|
The range operator (..) isn't overloadable, so bigint can't make it handle Math::BigInt objects.
I don't know why the range operator isn't overloadable. Maybe it's related to its complexity as an operator. Even if the range operator was overloadable, it's not actually used when doing for (x..y). That's the reason why for (x..y) is efficient.
| [reply] [d/l] [select] |
|
|
Thanks for the simple and accurate answer, and thanks to everyone else who posted.
| [reply] |
Re: big integers forcing me to be a C programmer: "range iterator outside integer range"
by BrowserUk (Patriarch) on May 07, 2009 at 11:30 UTC
|
It's a silly point, but if the delta of your range is anything like a reasonable number, you can still use the iterator for; with a little ingenuity:
my $x = Math::BigNum->new( 2 ) ** 1024;
for my $delta ( 1 .. 2 ) {
print $x + $delta;
}
Whether that satisfies is a personal taste thing I think.
Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
"Science is about questioning the status quo. Questioning authority".
In the absence of evidence, opinion is indistinguishable from prejudice.
| [reply] [d/l] |
Re: big integers forcing me to be a C programmer: "range iterator outside integer range"
by BrowserUk (Patriarch) on May 07, 2009 at 10:49 UTC
|
The simple answer is no. Perl limits its range iterators to integers. But even if it allowed floating point iterators it wouldn't help you, as there is no binary floating point representation that can accurately hold a 315,653(*) 309 digit integer!
(*Perl lied to me! Don't use bignum; and use Math::BigInt; in the same code. It appears to get confused!)
Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
"Science is about questioning the status quo. Questioning authority".
In the absence of evidence, opinion is indistinguishable from prejudice.
| [reply] [d/l] [select] |
|
|
| [reply] |
|
|
] Perl> print for 1 .. 2**62;;
1
2
3
4
5
6
7
8
9
10
11
I won't post the rest, so you'll have to take my word that it does actually get beyond 2**31-2 :)
Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
"Science is about questioning the status quo. Questioning authority".
In the absence of evidence, opinion is indistinguishable from prejudice.
| [reply] [d/l] |
|
|
|
|
Re: big integers forcing me to be a C programmer: "range iterator outside integer range"
by Anonymous Monk on May 07, 2009 at 10:36 UTC
|
The range operator is kind of primitive.splain echo Range iterator outside integer range|splain
Range iterator outside integer range (#1)
(F) One (or both) of the numeric arguments to the range operator "
+.."
are outside the range which can be represented by integers interna
+lly.
One possible workaround is to force Perl to use magical string inc
+rement
by prepending "0" to your numbers.
You can always range :)
sub range {
my( $start, $end ) = @_;
my @ret;
while($start <= $end ){
push @ret, $start;
$start++;
}
return @ret;
}
use bignum;
my $x = 2**1024
for(range( $x , $x+2 )) {
say
}
| [reply] [d/l] [select] |
Re: big integers forcing me to be a C programmer: "range iterator outside integer range"
by syphilis (Archbishop) on May 07, 2009 at 10:52 UTC
|
... the C-style loop allows it only when I use bignum (but not Math::BigInt)
You can use the C-style loop with Math::BigInt, but you just have to create $x in a slightly different way - eg:
use warnings;
use strict;
use feature 'say';
use Math::BigInt;
my $x = Math::BigInt->new(1);
$x <<= 1024;
for(my $i = $x; $i <= $x + 2; $i++) {
say $i;
}
The C-style loop works with both bignum and Math::BigInt because it makes use of operators that are overloaded. Unfortunately, the '..' operator is not currently overloaded, and that's why the second loop fails.
Cheers, Rob | [reply] [d/l] |
|
|
>perl -MMath::BigInt -le"my $x = Math::BigInt->new(2) ** Math::BigInt-
+>new(1024); print $x"
1797693134862315907729305190789024733617976978942306572734300811577326
+758055009631327084773224075360211201138798713933576587897688144166224
+928474306394741243777678934248654852763022196012460941194530829520850
+057688381506823424628814739131105408272371633505106845862982399472459
+38479716304835356329624224137216
It can even be simplified
>perl -MMath::BigInt -le"my $x = Math::BigInt->new(2) ** 1024; print $
+x"
1797693134862315907729305190789024733617976978942306572734300811577326
+758055009631327084773224075360211201138798713933576587897688144166224
+928474306394741243777678934248654852763022196012460941194530829520850
+057688381506823424628814739131105408272371633505106845862982399472459
+38479716304835356329624224137216
| [reply] [d/l] [select] |
|
|
The direct equivalent works just fine
I was thinking that the "direct equivalent" would be:
my $x = Math::BigInt->new(2**1024);
which doesn't work quite so well :-)
Cheers, Rob | [reply] [d/l] |
|
|
Re: big integers forcing me to be a C programmer: "range iterator outside integer range"
by JavaFan (Canon) on May 07, 2009 at 11:50 UTC
|
Just use magical increment.
use bignum;
my $x = 2**1024;
for ("A$x" .. "A${\($x+2)}") {
say substr $_, 1;
}
| [reply] [d/l] |
Re: big integers forcing me to be a C programmer: "range iterator outside integer range"
by NetWallah (Canon) on May 07, 2009 at 17:45 UTC
|
This works, and IMHO is reasonably readable:
my $x = 2**1024;
for( map {$x+$_} 0..2){
print qq|$_\n|;
}
..to maintain is to slowly feel your soul, sanity and sentience ebb away as you become one with the Evil.
| [reply] [d/l] |