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