Beefy Boxes and Bandwidth Generously Provided by pair Networks
Don't ask to ask, just ask
 
PerlMonks  

Re^7: Largest integer in 64-bit perl (RFC)

by LanX (Saint)
on Jun 02, 2025 at 21:18 UTC ( [id://11165214]=note: print w/replies, xml ) Need Help??


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

> 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://11165214]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others romping around the Monastery: (2)
As of 2025-06-22 05:59 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found

    Notices?
    erzuuliAnonymous Monks are no longer allowed to use Super Search, due to an excessive use of this resource by robots.