Beefy Boxes and Bandwidth Generously Provided by pair Networks
P is for Practical
 
PerlMonks  

Re^5: Largest integer in 64-bit perl

by BillKSmith (Monsignor)
on Jun 02, 2025 at 14:50 UTC ( [id://11165205]=note: print w/replies, xml ) Need Help??


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

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://11165205]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others exploiting the Monastery: (2)
As of 2026-04-11 02:27 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found

    Notices?
    hippoepoptai's answer Re: how do I set a cookie and redirect was blessed by hippo!
    erzuuliAnonymous Monks are no longer allowed to use Super Search, due to an excessive use of this resource by robots.