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