in reply to How to portably determine integer limits?

The question is, which integer limits do you mean? The suggested POSIX INT_MAX and INT_MIN, and $Config {intsize} gives information about the native integers of your system. But that's not necessarely the same as the integer range of your Perl! If you build your Perl to have 64 bit integers POSIX::INT_MAX might still be 2147483647 and $Config {intsize} be 4. But then Perl is using longlongs as integers, and you should be looking at $Config {longlongsize}.

Abigail

  • Comment on Re: How to portably determine integer limits?

Replies are listed 'Best First'.
Re: Re: How to portably determine integer limits?
by Anonymous Monk on Oct 30, 2003 at 00:48 UTC
    >The question is, which integer limits do you mean?

    Ok - I mean the min/max integer value for a scalar $i at the point where $i-- or $i++ will overflow and fail to return the expected value.

    I want to minimise the use of Math::BigInt where possible, so I'm looking to do something like:

    $integer_upper_limit = Math::BigInt->new($whatever_the_upper_limit_i +s); $number = get_integer_number_string_from_somewhere(); $number = Math::BigInt->new($number) if $integer_upper_limit->bcmp($ +number) < 0;
    Ditto for negative.

    Hope that make better sense!

    Edit by tye, change PRE to CODE around not-short lines

      Ok - I mean the min/max integer value for a scalar $i at the point where $i-- or $i++ will overflow and fail to return the expected value.
      Ah, that's yet another question. First of all, Perl numbers don't "overflow" in the sense that adding 1 to a really big positive number gives you are really small negative number.

      Say you have:

      $i = 0; $i ++ while forever;
      What happens is:
      • $i starts life as a value where its value is represented as an integer.
      • At one moment, the integer has insufficient bits to represent $i. Then perl starts using a floating point number, typically a double.
      • Due to rounding it won't happen if you keep adding 1, but if you keep increasing $i, even the floating point number will run out of bits; then $i becomes "not a number".
      If your double has more bits than your integer (a very typical situation, specially in older perls, is having 32 bit integers and 64 bit doubles), there's an interesting situation after the change of representation. 64 bit doubles still have something like 53 bits of precision. So, even with 32 integers, you can still store numbers needing 53 bits without losing precision. And I guess something similar will happen if you have 64 bit integers, and 128 bit doubles.

      Abigail

        Due to rounding it won't happen if you keep adding 1, but if you keep increasing $i, even the floating point number will run out of bits; then $i becomes "not a number".
        If it's IEEE-754 floating point it should become +Inf...

        Ok, not really. At some point the exponent is going to be large enough that you can't represent a +1 difference in the significand, and $i+1 == $i;
        # nvtype='double', nvsize=8; perl -le 'for$ex(0..128){$i=2**$ex;print"$ex $i"and last if$i==$i+1}'

      I didn't see any good answers to this given. I'd do:

      my $x= 1+~0; $x *= 2 while $x != $x+1; print "You can safely use integer values between ", -$x/2, " and ", $x/2, $/; # -$x, " and ", $x-1, $/;
      where you could choose to use that last line instead of the second-to-last line if you aren't paranoid like me.

                      - tye