Skip to content

Commit

Permalink
Fix exponentiation by large negative Ints...
Browse files Browse the repository at this point in the history
and speedup exponentiation by any sized negative Ints. The fix is to
revert the incorrect underflow check added in 6f6fd1f and the speedup
comes from bypassing `&infix:</>` when creating the `1 / $power` Rational
since we have some knowledge about the values. Also switch to use
`.Failure` on the exceptions for smaller bytecode (though `&infix:<**>`
is still too large to inline).
  • Loading branch information
MasterDuke17 committed Apr 26, 2022
1 parent 51c00fd commit c66c98f
Show file tree
Hide file tree
Showing 2 changed files with 6 additions and 6 deletions.
10 changes: 4 additions & 6 deletions src/core.c/Int.pm6
Expand Up @@ -381,23 +381,21 @@ multi sub infix:<%%>(int $a, int $b --> Bool:D) {
nqp::hllbool(nqp::iseq_i(nqp::mod_i($a, $b), 0))
}

my constant UINT64_UPPER = nqp::pow_I(2, 64, Num, Int);

multi sub infix:<**>(Int:D $a, Int:D $b --> Real:D) {
my $power;
if nqp::isge_I($b, 0) {
$power := nqp::pow_I($a, $b, Num, Int);
# when a**b is too big nqp::pow_I returns Inf
nqp::istype($power, Int)
?? $power
!! Failure.new(X::Numeric::Overflow.new)
!! X::Numeric::Overflow.new.Failure
}
else {
$power := nqp::pow_I($a, nqp::neg_I($b, Int), Num, Int);
# when a**b is too big nqp::pow_I returns Inf
nqp::istype($power, Num) || (nqp::isge_I($power, UINT64_UPPER) && nqp::isne_I($a, 0))
?? Failure.new(X::Numeric::Underflow.new)
!! 1 / $power
nqp::istype($power, Num) || (($power := CREATE_RATIONAL_FROM_INTS(1, $power, Int, Int)) == 0 && nqp::isne_I($a, 0))
?? X::Numeric::Underflow.new.Failure
!! $power
}
}

Expand Down
2 changes: 2 additions & 0 deletions src/core.c/Rat.pm6
Expand Up @@ -31,6 +31,8 @@ my class Rat is Cool does Rational[Int, Int] {
}
}

my constant UINT64_UPPER = nqp::pow_I(2, 64, Num, Int);

my class FatRat is Cool does Rational[Int, Int] {
method FatRat(FatRat:D:) { self }
method Rat(FatRat:D:) {
Expand Down

0 comments on commit c66c98f

Please sign in to comment.