Re: Infinity and Inf?
by ikegami (Patriarch) 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 C-style 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+2-1
999999999999999
DB<85> p 1e+15-1
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+4-5
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**31-2) {print;last if $x++>5}
1234567
DB<47> $x=0;for(1..2**31-1) {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] |