in reply to Re^4: Largest integer in 64-bit perl
in thread Largest integer in 64-bit perl

I would expect any language that does not support an operation to not allow attempts to use it. Perl does not directly support 64-bit integer exponentiation. without strong typing, it has no way to know that we expect it. What it does do when we try to raise an integer to an integer power is exact if the result is less than 2**53, and almost always 'good enough" the rest of the time. Perhaps there should be an optional warning when it attempts to cast a result greater than 2**53 and less than 2**63 to an integer.
Bill

Replies are listed 'Best First'.
Re^6: Largest integer in 64-bit perl
by LanX (Saint) on Jun 02, 2025 at 15:17 UTC
    > without strong typing, it has no way to know that we expect it.

    I disagree, at least if the operands were integer and the result is between max-float-precision and max-integer-precision (2**53 and 2**64 in our case) you can assume an integer was wanted.

    Of course it's not trivial (if ever) to solve this generally for instance for $x=2**0.5 and $y=$x**2 since the square-root of 2 isn't rational.

    Or even $x=2/3 and 27**$x == 9 because $x isn't loss-free in binary floats.

    > Perhaps there should be an optional warning when it attempts to cast a result greater than 2**53 and less than 2**63 to an integer.

    I think this should be part of a (bigger) pragma to address this.

    for instance will Perl happily do this

    DB<25> p 27**(2/3) 9 DB<26> p 27**(2/3) == 9 DB<27> printf "%.15f", 27**(2/3) 8.999999999999998 DB<28>

    update

    And before the Perl bashing hits in, Python isn't that much better

    >>> 27**(2/3) 8.999999999999998 >>> 27**(2/3)==9 False >>>

    Cheers Rolf
    (addicted to the Perl Programming Language :)
    see Wikisyntax for the Monastery

      > I disagree, at least if the operands were integer and the result is between max-float-precision and max-integer-precision (2**53 and 2**64 in our case) you can assume an integer was wanted.

      Here a POV to force ** into producing an integer where it obviously should.

      Kind of over-engineered and under-tested.

      I first used Math::BigInt as backend but integer turned out to be easier.

      Since integer is core, it shouldn't be complicated to implement this right away,

      use v5.10; use warnings; use Config; use constant { MAX_FLOAT => eval($Config{nv_overflows_integers_at}."-1"), MAX_INT => ~0, BACKEND => "integer", }; sub power{ my ($base,$exp) = @_; my $float = $base ** $exp; return $float + 0 # Explicitely coerce to IV if possible if $float <= MAX_FLOAT; return $float # no integer possible if $float > MAX_INT or $base != int($base) or $exp != int($exp); if (BACKEND eq "BigInt") { use Math::BigInt; my $result = Math::BigInt->new($base)->bpow($exp); return hex($result->as_hex()) } elsif (BACKEND eq "integer") { use integer; return int($base ** $exp); } else { die "Unknown Backend: ". BACKEND; } } sub compare { my ($b,$e) = @_; say "=== comparing $b^$e"; my $old = $b**$e; my $new = power($b,$e); for my $val ($old,$new) { say "--- $val"; # use Devel::Peek; # use Data::Dump; # say "is integer" if $val == int($val); # ddx ($val); # Dump($val); say "$_: \t", $val+$_ for -1,1; } say "="; } compare(@$_) for [2,50],[2,63];

      perl /home/lanx/perl/pm/int_pow.pl === comparing 2^50 --- 1.12589990684262e+15 is integer -1: 1125899906842623 1: 1125899906842625 --- 1125899906842624 is integer -1: 1125899906842623 1: 1125899906842625 = === comparing 2^63 --- 9.22337203685478e+18 is integer -1: 9.22337203685478e+18 1: 9.22337203685478e+18 --- 9223372036854775808 is integer -1: 9223372036854775807 1: 9223372036854775809 =

      update

      since integer is only meant to operate with signed integers I'm not too confident this is reliable in the range between 2**63 and 2**64.

      More testing needed.

      update

      well, seems not to be a good idea to rely on integer , see integer pragma buggy? (ANSWERED)

      Cheers Rolf
      (addicted to the Perl Programming Language :)
      see Wikisyntax for the Monastery