Skip to content

Render a domain error's argument in E notation, so its message stays short [patch] - #192

Merged
matt-edmondson merged 1 commit into
mainfrom
fix/190-bounded-domain-message
Nov 10, 2026
Merged

matt-edmondson merged 1 commit into
mainfrom
fix/190-bounded-domain-message

Conversation

@matt-edmondson

Copy link
Copy Markdown
Contributor

Fixes #190

What was wrong

Every domain check passed the PreciseNumber argument itself as ActualValue. ArgumentOutOfRangeException.Message renders that value with ToString(), which writes fixed point:

  • Reading the message of Sqrt(-1e-2147483648) threw OverflowException.
  • Log(-1e2000000000) and Asin(1e2000000000) ran out of memory.
  • Log(-1e-200000000) took seconds to build a 200-million-character string.

As a result, a catch (Exception e) { log(e.Message); } handler crashed or stalled instead of reporting the domain error.

Change

A single DomainError(paramName, value, message) helper, in PreciseNumber.Exponentials.cs, builds the exception for all ten checks:

  • Log, and the Log2/Log10 path
  • LogP1
  • Acosh
  • Atanh
  • the two even-root checks in RootN/Sqrt
  • Asin
  • Acos
  • the fractional power of a negative base in Pow

The argument is carried as an E-format string with up to 30 fractional digits. A typical argument therefore keeps every digit (-12.5 → -1.25E+001), and an extreme one stays a few dozen characters long.

ActualValue is now that string rather than the PreciseNumber. Nothing in the repo read it as a number.

Tests

PreciseNumberDomainErrorTests triggers every domain check with arguments of ±1e±2000000000 and ±1e-2147483648, as each check's domain allows, plus -1e-200000000 for Log. Each test reads .Message and asserts it is under 1,000 characters. Two more tests pin the rendering itself: the ParamName, ActualValue and message of Sqrt(-12.5), and 30 fractional digits of -π.

With the library change stashed, all 31 new tests fail. Some fail by throwing from .Message. The Log cases take 8 to 11 s each to build their message before failing on its length. With the change, the full suite passes: 617/617. I also added the new test file to the test-structure paragraph in CLAUDE.md.


Generated by Claude Code

…short [patch]

Every domain check passed the PreciseNumber argument itself as
ActualValue, and ArgumentOutOfRangeException.Message renders that with
ToString(), which writes fixed point. Reading the message of
Sqrt(-1e-2147483648) threw OverflowException, Log(-1e2000000000) and
Asin(1e2000000000) ran out of memory, and Log(-1e-200000000) spent
seconds building a 200-million-character string, so a handler that logs
e.Message crashed or stalled instead of reporting the domain error.

All ten checks now build their exception through DomainError, which
carries the argument in E notation with up to thirty fractional digits.

Fixes #190

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

sonarqubecloud Bot commented Nov 7, 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