Skip to content

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

Merged
matt-edmondson merged 2 commits into
mainfrom
fix/126-format-strings
Nov 4, 2026
Merged

matt-edmondson merged 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

@matt-edmondson
matt-edmondson merged commit 00f1bfd into main Nov 4, 2026
15 checks passed
@matt-edmondson
matt-edmondson deleted the fix/126-format-strings branch November 4, 2026 01:03
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