http://www.perlmonks.org?node_id=858188

LanX has asked for the wisdom of the Perl Monks concerning the following question:

Hi

could someone point me to a good source where and how the constants Inf and Infinity can be used in Perl?

I tried to define a lazy iteration and I know that I can redefine the constant for my needs

DB<6> $x=0;for (1..Inf) { print; last if $x++ >5} Range iterator outside integer range at (eval 10)[/usr/share/perl/5.10 +/perl5db.pl:638] line 2. DB<7> sub Inf() {1000} DB<8> $x=0;for (1..Inf) { print; last if $x++ >5} 1234567

But I would be interested to know the canonical/intended way to use those constants, before messing around with internals!

Unfortunately grepping thru the perlocs didn't show much information.

It seems to be a feature of Math::BigInt but why can I see the constant without using BigInt???

There are also confusing references to a IEEE 754 standard. In JS a division by zero results to Infinity, but in Perl it's an error?

Please enlighten me about what is happening here...

Cheers Rolf

Replies are listed 'Best First'.
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.

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

      Cheers Rolf

        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
      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;
        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.
        > Or with less obfuscation ...

        > use constant MAXINT => ~0; Not true on my box..

        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.

        Cheers Rolf

      > It's not a symbol (i.e., not a constant, a sub or a builtin).

      FYI:

      DB<8> print $::{Inf} *main::Inf

      Cheers Rolf

        $ 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?
Re: Infinity and Inf?
by zentara (Archbishop) on Aug 31, 2010 at 18:52 UTC
    Here is an old script posted by someone: ( also see How to create nan/inf )
    #!/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";

    I'm not really a human, but I play one on earth.
    Old Perl Programmer Haiku ................... flash japh
Re: Infinity and Inf?
by zentara (Archbishop) on Aug 31, 2010 at 18:44 UTC
    It seems to me infinity is paid more attention to in modules that require it mathematically. Maybe google for "infinity Perl PDL" and see it's usages and restrictions.

    Infinite infinites boggles the mind. :-)


    I'm not really a human, but I play one on earth.
    Old Perl Programmer Haiku ................... flash japh
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.
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.

      Thanks I saw the thread but since it's > 2.5 years old I hoped there'll be something new...

      According to Re: $array[ 'Infinity' ] Inf is so buggy that it shouldn't be used.

      8(

      Cheers Rolf

        Not buggy, platform specific.