Re: Infinity and Inf?
by ikegami (Pope) on Aug 31, 2010 at 17:45 UTC

Range iterator outside integer range
Infinity is a float, and the range operator requires an integer. Both of the following would get you the max int:
use constant MAX_INT => unpack('J', pack('j', 1));
use constant MAX_INT => 0+sprintf('%u', 1);
You could also use a Cstyle loop:
for (my $_ = 1; ; ++$_)
I tried to define a lazy iteration and I know that I can redefine the constant for my needs
It's not a symbol (i.e., not a constant, a sub or a builtin).
$ perl e'Inf()'
Undefined subroutine &main::Inf called at e line 1.
$ perl Mstrict e'Inf'
Bareword "Inf" not allowed while "strict subs" in use at e line 1.
Execution of e aborted due to compilation errors.
It's just a string that some underlying C libraries numify to a value representing infinity.
It seems to be a feature of Math::BigInt
It's an feature of the hardware floating point number format. Math::Big* may also support it, but that's unrelated.
 [reply] [d/l] [select] 

> It's not a symbol (not a constant or function).
hmm strange:
DB<8> print 5+Inf
inf
DB<9> use strict;print 5+Inf
Bareword "Inf" not allowed while "strict subs" in use at (eval 13)[/us
+r/share/perl/5.10/perl5db.pl:638] line 2.
 [reply] [d/l] 

How is that weird? Barewords are autoquoted when strict doesn't prevent it.
$ perl E'$x=abc; say $x'
abc
$ perl E'$x=Inf; say $x'
Inf
Nothing special there. Like I said, only its numification is special.
$ perl E'$x=Inf; say 0+$x'
inf
 [reply] [d/l] [select] 



Both of the following would get you the max int:
use constant MAX_INT => unpack('J', pack('j', 1));
use constant MAX_INT => 0+sprintf('%u', 1);
Or with less obfuscation ...
use constant MAXINT => ~0;
 [reply] [d/l] [select] 

I wouldn't call it obfuscation, it's simply the Perl spelling of (unsigned int)1. I didn't realise that the bitwise negation operator (~) returned a UV.
 [reply] [d/l] [select] 

DB<1> print ~0
4294967295
DB<2> print ~0+1
4294967296
DB<3> print ~0+2
4294967297
...
DB<12> print ~0*2**18
1.12589990658048e+15
...
DB<15> print ~0*2**17
562949953290240
...
DB<33> p unpack('J', pack('j', 1));
4294967295
DB<34> p 0+sprintf('%u', 1);
4294967295
The MAX_INT is somewhere between 2**49 and 2**50!
UPDATE:
DB<81> p 999999999999999+1
1e+15
DB<82> p 999999999999998+1
999999999999999
DB<83> p 999999999999998+2
1e+15
DB<84> p 999999999999998+21
999999999999999
DB<85> p 1e+151
999999999999999
Seems to depend on the decimal representation of the mantissa of the floating point arithmetics.
UPDATE:
to be more precise, integers still work internally for higher numbers even if they can't be represented.
DB<88> p 999999999999998+45
999999999999997
...
DB<96> p 999999999999999+2**52 2**52
999999999999999
DB<97> p 999999999999999+2**53 2**53
1e+15
UPDATE
Last but not least
DB<32> $x=0;for(1..2**31) {print;last if $x++>5}
Range iterator outside integer range at (eval 36)[/usr/share/perl/5.10
+/perl5db.pl:638] line 2.
DB<33> $x=0;for(1..2**30) {print;last if $x++>5}
1234567
DB<34> $x=0;for(1..~0) {print;last if $x++>5}
Range iterator outside integer range at (eval 45)[/usr/share/perl/5.10
+/perl5db.pl:638] line 2.
The range operator seems only to be implemented for signed 32bits integers...so MAX_INT wouldn't even help here!
DB<46> $x=0;for(1..2**312) {print;last if $x++>5}
1234567
DB<47> $x=0;for(1..2**311) {print;last if $x++>5}
Range iterator outside integer range at (eval 51)[/usr/share/perl/5.10
+/perl5db.pl:638] line 2.
 [reply] [d/l] [select] 











> It's not a symbol (i.e., not a constant, a sub or a builtin).
FYI:
DB<8> print $::{Inf}
*main::Inf
 [reply] [d/l] 

$ perl wle'print $::{Inf}'
Use of uninitialized value in print at e line 1.
Are you sure you didn't create it (explicitly or via autovivification) earlier in your session?  [reply] [d/l] 

Re: Infinity and Inf?
by zentara (Archbishop) on Aug 31, 2010 at 18:52 UTC

#!/usr/bin/perl w
$pinf = 1e9999; # positive infinity
$ninf = $pinf; # negative infinity
$nan = $pinf/$pinf; # not a number
$\ = "\n";
print "pos inf: ", $pinf;
print "neg inf: ", $ninf;
print "not a num: ", $nan;
print "two pos inf: ", 2 * $pinf;
print "two nan: ", 2 * $nan;
#prints, as it should, according to the IEEE spec
#pos inf: Infinity
#neg inf: Infinity
#not a num: NaN
#two pos inf: Infinity
#two nan: NaN
print "NaN ", NaN,"\n";
 [reply] [d/l] 
Re: Infinity and Inf?
by zentara (Archbishop) on Aug 31, 2010 at 18:44 UTC

 [reply] 
Re: Infinity and Inf?
by moritz (Cardinal) on Sep 01, 2010 at 10:39 UTC

But I would be interested to know the canonical/intended way to use those constants, before messing around with internals!
There is, if you're willing to use v6;:
$ perl6 e 'for 1..Inf { .say; last if $_ == 5 }'
1
2
3
4
5
Perl 6  links to (nearly) everything that is Perl 6.
 [reply] [d/l] [select] 
Re: Infinity and Inf?
by dasgar (Priest) on Aug 31, 2010 at 17:39 UTC

I'm not familiar with this topic, so I did a Google search on "perl infinity". The first link was to a PM node ($array[ 'Infinity' ]). Not sure if that will help, but it might have some useful information for you.
 [reply] 

 [reply] 

Not buggy, platform specific.
 [reply] 