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

When I referred to "Application which require integers ...", I assumed that the reason that they required integers was that they needed mathematically exact results. Yes, the typed languages usually require you to explicitly specify an appropriate integer type. I still believe that my conclusion holds in this case.
Bill

Replies are listed 'Best First'.
Re^4: Largest integer in 64-bit perl
by LanX (Saint) on Jun 01, 2025 at 10:43 UTC
    I'm no expert in statically typed languages..

    ... how many of them support x^y with integers?

    Those exponentiation algorithms are normally implemented for real numbers and produce a float.

    The core problem we saw and most Perl experiments here is that 2**53 is a float whose error margin doesn't allow a consistent conversion to 64 bit integer anymore.

    If your statically typed language doesn't support this out-of-the-box - and Perl is build on top of C - your statement is just comparing apples with oranges.

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

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

Re^4: Largest integer in 64-bit perl
by ikegami (Patriarch) on Jun 01, 2025 at 10:10 UTC

    You'll have the same problems using doubles near 2**53 in another language. You'd have to use 64-bit ints to avoid that. Same in Perl. It doesn't hold.

      Here is a few examples of the same expression in strawberry perl 5.38.2 and in the gfortran packaged with it. I believe the fortran.
      use strict; use warnings; use integer; use feature 'say'; my $base = 3; my $power = 33; my $result = $base ** $power; printf "%d\n", $result; $power = 38; $result = $base ** $power; printf "%d\n", $result
      program fort integer*8 base, power integer*8 result base = 3 power = 33 result = base ** power +1; print *, result power = 38 result = base ** power +1; print *, result end program

      RESULTS

      C:\Users\Bill\forums\monks>perl power3.pl 5559060566555523 1350851717672992000 C:\Users\Bill\forums\monks>gfortran -o power3 power3.f90 C:\Users\Bill\forums\monks>power3.exe 5559060566555524 1350851717672992090
      Bill
        The first result is identical, you are adding 1 in Fortran only.

        The second one needs 61 bits and is outside float precision in Perl.

        Edit

        This shows the same result and that the exponentiation is the real "culprit".

        DB<11> $x=1; $x*=3 for 1..38; say $x 1350851717672992089 DB<12>

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