Skip to content

Commit

Permalink
Throw on underflow in infix:<**>(Int, Int)
Browse files Browse the repository at this point in the history
Fixes RT#130369: https://rt.perl.org/Ticket/Display.html?id=130369

The behaviour in the ticket is observed due to the power being small
enough that overflow doesn't occur when we raise a number to absolute
power, yet large enough that when we divide 1 by it, it underflows.

- Add extra check for overflow condition to throw underflow exception
    if the power is negative
- Check for zero result and throw underflow if the base is not zero
  • Loading branch information
zoffixznet committed Dec 18, 2016
1 parent fb38190 commit 7a642f8
Showing 1 changed file with 8 additions and 3 deletions.
11 changes: 8 additions & 3 deletions src/core/Int.pm
Expand Up @@ -284,10 +284,15 @@ multi sub infix:<%>(int $a, int $b) returns int {
}

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

multi sub infix:<**>(int $a, int $b) returns int {
Expand Down

0 comments on commit 7a642f8

Please sign in to comment.