You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Formatting a value with an extreme exponent throws or produces a huge string #75
ToString and TryFormat always write fixed-point notation, including every zero the exponent implies. Parse accepts any exponent that fits in an int, so a value can parse successfully and then fail to format, or format as an enormous string. Observed on 2.0.3:
Value
ToString()
TryFormat into 64 chars
1E-2147483648
throws OverflowException
throws ArgumentOutOfRangeException
1E2147483647
throws ArgumentOutOfRangeException
throws ArgumentOutOfRangeException
1E-1000000
1,000,002 characters
returns false
1E1000000
1,000,001 characters
returns false
TryFormat should return false when the destination is too small rather than throw, as it does for the last two rows.
Cause
The formatting paths do their length arithmetic in int and negate or take the absolute value of the exponent:
ToString sizes its buffer as SignificantDigits + int.Abs(Exponent) + ... (PreciseNumber.cs lines 334 to 338). int.Abs throws for int.MinValue, and the sum overflows for exponents near int.MaxValue.
CountDecimalDigits returns int.Abs(Exponent) (PreciseNumber.cs line 657).
TryFormat computes fractionalDigits = -Exponent (PreciseNumber.cs line 1133), which wraps for int.MinValue, and derives slice lengths from the exponent.
#72 fixed this pattern in the conversion paths with range checks and by widening to long, but left formatting alone.
Suggested fix
Do the length arithmetic in long. TryFormat then returns false for any length that doesn't fit, and ToString fails with a clear exception when the text can't exist as a string.
Consider scientific notation for extreme exponents. Supporting the "E" and "G" standard format strings, or switching the default past some exponent the way double does, would make these values printable at all. Check how the format argument is handled today before choosing.
Add tests for int.MinValue and int.MaxValue exponents across ToString, TryFormat, and CountDecimalDigits.
Activity