Skip to content

1e2000000000 + 1e-2000000000 throws ArgumentOutOfRangeException ("exponent must be non-negative"): exponent alignment wraps int #135

Description

@matt-edmondson

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.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions