What happens
Pow special-cases a base of One (SignificantNumber/SignificantNumber.cs:599) but not NegativeOne. When the base is -1 and the integer power is beyond the range of a double, PowByLogarithm computes:
Math.Log(1) * power.To<double>(), which is 0 · ∞ = NaN (line 643).
- It then falls back to
Log10OfMagnitude(-1) * ∞, which is NaN again.
FromLog10OfMagnitude (around lines 713-718) sees a non-finite value and throws. The message says "too small" only because NaN > 0 is false.
S("-1").Pow(S("2E308")) // throws OverflowException: The result is too small to represent. expected 1
S("-1").Pow(S("-1E400")) // throws the same expected 1
S("-1").Pow(S("2" + new string('0', 310) + "1")) // throws expected -1
S("-1").Pow(S("1E308")) // 1 (correct, still inside double range)
Why it matters
The README documents -1, 0 and 1 as exact values. (-1)^n for an integer n always has an exact answer (±1), whatever the size of n. Callers get an exception with a misleading message instead. Impact is limited to very large exponents, but the fix is a two-liner.
Suggested fix
Next to the Equal(this, One) check:
else if (Equal(this, NegativeOne) && PreciseNumber.IsInteger(power))
{
return PreciseNumber.IsEvenInteger(power) ? One : NegativeOne;
}
IsInteger and IsEvenInteger work on the PreciseNumber directly, without going through a double.
Acceptance criteria
(-1)^(2E308) == 1, (-1)^(-1E400) == 1, and (-1)^(odd integer beyond 1E308) == -1.
- A non-integer power of -1 keeps its current behaviour.
What happens
Powspecial-cases a base ofOne(SignificantNumber/SignificantNumber.cs:599) but notNegativeOne. When the base is -1 and the integer power is beyond the range of a double,PowByLogarithmcomputes:Math.Log(1) * power.To<double>(), which is0 · ∞ = NaN(line 643).Log10OfMagnitude(-1) * ∞, which is NaN again.FromLog10OfMagnitude(around lines 713-718) sees a non-finite value and throws. The message says "too small" only becauseNaN > 0is false.Why it matters
The README documents -1, 0 and 1 as exact values.
(-1)^nfor an integernalways has an exact answer (±1), whatever the size ofn. Callers get an exception with a misleading message instead. Impact is limited to very large exponents, but the fix is a two-liner.Suggested fix
Next to the
Equal(this, One)check:IsIntegerandIsEvenIntegerwork on thePreciseNumberdirectly, without going through a double.Acceptance criteria
(-1)^(2E308) == 1,(-1)^(-1E400) == 1, and(-1)^(odd integer beyond 1E308) == -1.