Skip to content

fix(core): return error instead of panicking on negative power edge cases 💥#171

Merged
timfennis merged 1 commit into
masterfrom
bugfix/pow-negative-exponent-panics
Jun 2, 2026
Merged

fix(core): return error instead of panicking on negative power edge cases 💥#171
timfennis merged 1 commit into
masterfrom
bugfix/pow-negative-exponent-panics

Conversation

@timfennis
Copy link
Copy Markdown
Owner

Context

While fuzzing the pipeline for panics, I found that the integer-power (^) path aborts the whole process on several negative-exponent inputs. These are recoverable runtime errors that should never crash the interpreter — same class of bug as the recent integer division-by-zero fix (#168).

The crashes

Input Panic
2 ^ (1/-1) right hand side must not be negative (int.rs:117)
0 ^ -1 denominator == 0 (num-rational)
0 ^ (2/-1) right hand side must not be negative

Root causeNumber::pow had two integer-exponent branches:

  • Int ^ Int handled negative exponents as the reciprocal 1/(base^|exp|), but with base 0 that builds BigRational::new(1, 0), which panics.
  • Int ^ Rational (integer-valued rational, e.g. 1/-1) didn't handle negatives at all — it called Int::pow directly, which panics unconditionally on a negative RHS.

The existing MAX_EXPONENT_BITS guard only checks magnitude, so it never caught these.

Changes

  • Added a Number::int_pow(base, exponent) helper that both integer-exponent branches route through. It returns a division by zero error for 0 ^ negative, computes the reciprocal rational for any other negative exponent, and otherwise returns the plain integer power. This also removes the previously duplicated negative-exponent logic.
  • Regression tests:
    • 900_bugs/bug0025_pow_negative_rational_exponent.ndc2 ^ (1/-1)1/2
    • 001_math/030_pow_zero_negative_exponent.ndc0 ^ -1division by zero
    • 001_math/031_pow_zero_negative_rational_exponent.ndc0 ^ (2/-1)division by zero

Valid cases verified unchanged: 2 ^ -11/2, 3 ^ (-4/2)1/9, 2 ^ 38, (1/2) ^ -38.

🤖

…ases 💥

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@timfennis timfennis merged commit b925b60 into master Jun 2, 2026
1 check passed
@timfennis timfennis deleted the bugfix/pow-negative-exponent-panics branch June 2, 2026 06:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant