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
Parse throws OverflowException for "0e99999999999" and for representable values near exponent int.MinValue, so ToString("E") output there can't be parsed back #178
In Parse (PreciseNumber/PreciseNumber.cs:1291), exponent = checked(exponent - decimalDigits) subtracts every written fraction digit — including padding zeros — in checked int arithmetic before the value is normalized. The exponent text also goes through int parsing even when the significand is zero.
Reproduced at 907bd2d (invariant culture, NumberStyles.Float):
varx=PreciseNumber.Parse("1e-2147483646",inv);// finevars=x.ToString("E",inv);// "1.000000E-2147483646"PreciseNumber.TryParse(s,NumberStyles.Float,inv,out_);// false — can't read its own outputPreciseNumber.Parse("2.500E-2147483647",inv);// OverflowException; the value 25e-2147483648 is representablePreciseNumber.Parse("1.0e-2147483648",inv);// OverflowException; "1e-2147483648" parses finePreciseNumber.Parse("0e99999999999",NumberStyles.Float,inv);// OverflowException; decimal and double return 0
Why it matters
At these magnitudes the plain format would be a ~2 GB string, so "E" is the only text form that can round-trip a value — and it doesn't. Serialized values (e.g. through a round-trip string JSON converter) at the extreme end of the range fail to load. A zero with a large written exponent is valid input that every BCL numeric type accepts.
Suggested fix
Strip trailing zeros from the collected digits (adjusting decimalDigits) before computing the exponent, or do the exponent arithmetic in long and range-check only after normalizing.
Return Zero when the significand is zero, regardless of the exponent text (parse the exponent as long/saturating so huge exponents don't throw first).
Acceptance: each input above parses to the expected value, and Parse(x.ToString("E")) round-trips for values with exponents within 10 of int.MinValue/int.MaxValue.
Priority: Medium. It only affects values at the very edge of the exponent range, but "E" is the only text form that can round-trip those values, and 0e<huge> is valid input that every BCL numeric type accepts.
Area / suggested assignment:Parse exponent arithmetic (PreciseNumber/PreciseNumber.cs ~1291)
Next step: trim trailing zeros or do the exponent arithmetic in long, return Zero early when the significand is zero, and add round-trip tests near int.MinValue/int.MaxValue.
Activity
matt-edmondson commentedon Oct 29, 2026
Triage
"E"is the only text form that can round-trip those values, and0e<huge>is valid input that every BCL numeric type accepts.Parseexponent arithmetic (PreciseNumber/PreciseNumber.cs~1291)$"{x}"/ StringBuilder.Append(x) never returns for a value with an extreme exponent: TryFormat returns false where ToString throws OverflowException #144 (closed) covered formatting at extreme exponents, which is the other half of this round-trip.Parse, but only for NBSP separators (Parse("1 234,5", fr-FR) throws where decimal returns 1234.5: a typed space doesn't match a no-break-space group separator #174), so watch for a merge conflict.long, returnZeroearly when the significand is zero, and add round-trip tests nearint.MinValue/int.MaxValue.Generated by Claude Code