Skip to content

Write C, P and custom format strings the way decimal does [patch] - #141

Open
matt-edmondson wants to merge 2 commits into
mainfrom
fix/126-format-strings
Open

matt-edmondson wants to merge 2 commits into
mainfrom
fix/126-format-strings

Conversation

@matt-edmondson

Copy link
Copy Markdown
Contributor

What was still broken

The ktsu.PreciseNumber 2.6.11 bump (which closed ktsu-dev/PreciseNumber#134) already made G, R, F, N and E work, as well as TryFormat and $"{x:F1}". These still threw FormatException from ToString, TryFormat and interpolation:

  • C and P
  • custom patterns such as "0.00" and "#,##0.0"

PreciseNumber refuses these formats on purpose.

Change

  • G, R, F, N and E (with an optional precision) still go to PreciseNumber, which writes them from the exact value.
  • Any other format goes through decimal when decimal holds the value exactly, and through double otherwise, which is the fallback the issue suggests. A format is now refused only when decimal or double would refuse it too.
  • TryFormat returns false when the destination is too small, in both paths.

Tests

SignificantNumberFormatTests checks the results against decimal's output under InvariantCulture and a comma-decimal culture. That culture is built by hand because the CI container runs in globalization-invariant mode. The tests cover:

  • ToString and TryFormat across F, N, E, C, P and custom patterns

  • a destination that is too small

  • interpolation and string.Format

  • values outside decimal's range and precision

  • the current culture when no provider is given

  • Without the library change, 26 of the 35 new cases fail.

  • With it, all 225 tests pass, with analyzers on.

Not in this PR

G<n> still differs from decimal: 1234.5 with "G3" gives 1230, where decimal gives 1.23E+03. The cause is in PreciseNumber, which never switches G<n> to scientific notation, and ktsu-dev/PreciseNumber#172 tracks it. Bumping PreciseNumber after #172 lands will fix it here as well.

Fixes #126


Generated by Claude Code

The ktsu.PreciseNumber 2.6.11 bump made G, R, F, N and E work, but C, P and
custom patterns such as "0.00" and "#,##0.0" still threw FormatException from
ToString, TryFormat and string interpolation.

Keep G, R, F, N and E on PreciseNumber, which writes them from the exact
value. Write any other format through decimal when it holds the value
exactly, and through double otherwise, so a format is refused only when
decimal or double would refuse it too. TryFormat returns false when the
destination is too small.

Fixes #126

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017vfJW6Hi85XX4Q7wr44mWe
…ents, per SonarCloud

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017vfJW6Hi85XX4Q7wr44mWe
@sonarqubecloud

sonarqubecloud Bot commented Nov 1, 2026

Copy link
Copy Markdown

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

Labels

None yet

Projects

None yet

2 participants