What's wrong
CommonizeSignificands subtracts the two exponents in unchecked int. With operands at opposite extremes, the difference wraps negative and is passed to Pow10, which rejects it with an unrelated ArgumentOutOfRangeException.
Where
PreciseNumber/PreciseNumber.cs:923-935 (CommonizeSignificands, which computes leftExponent - rightExponent), used by Add/Subtract (around line 1500) and Mod (line 1711).
Failure scenario
Confirmed with a scratch app:
var a = PreciseNumber.Parse("1e2000000000");
var b = PreciseNumber.Parse("1e-2000000000");
_ = a + b; // ArgumentOutOfRangeException: exponent must be a non-negative value (Pow10(-294967296))
Multiply and Divide report the same out-of-range condition as OverflowException (fixed in #109), so callers that catch OverflowException around arithmetic miss this one.
Suggested fix
- Compute the exponent difference as
long (or checked).
- When it cannot be represented, either throw
OverflowException, consistent with Multiply/Divide, or, better for Add, short-circuit. When the difference exceeds the working precision, the smaller operand cannot affect the result's significant digits.
- Add tests for
Add, Subtract and Mod with exponents ±2e9.
What's wrong
CommonizeSignificandssubtracts the two exponents in uncheckedint. With operands at opposite extremes, the difference wraps negative and is passed toPow10, which rejects it with an unrelatedArgumentOutOfRangeException.Where
PreciseNumber/PreciseNumber.cs:923-935(CommonizeSignificands, which computesleftExponent - rightExponent), used byAdd/Subtract(around line 1500) andMod(line 1711).Failure scenario
Confirmed with a scratch app:
MultiplyandDividereport the same out-of-range condition asOverflowException(fixed in #109), so callers that catchOverflowExceptionaround arithmetic miss this one.Suggested fix
long(orchecked).OverflowException, consistent withMultiply/Divide, or, better forAdd, short-circuit. When the difference exceeds the working precision, the smaller operand cannot affect the result's significant digits.Add,SubtractandModwith exponents ±2e9.