Skip to content

[patch] Keep NormalizedParameter.Normalize in [0, 1] for out-of-domain values and reject empty ranges - #412

Merged
matt-edmondson merged 1 commit into
mainfrom
fix/319-normalize-never-nan
Oct 9, 2026
Merged

matt-edmondson merged 1 commit into
mainfrom
fix/319-normalize-never-nan

Conversation

@matt-edmondson

Copy link
Copy Markdown
Contributor

Fixes #319

What changed

NormalizedParameter<T>.Normalize relied on Math.Clamp, which passes NaN straight through. The result:

  • Logarithmic(20, 20000).Normalize(-5) returned NaN for double
  • the decimal version threw OverflowException
  • a zero-width Linear(1, 1) produced NaN as well

Changes:

  • Logarithmic taper: a value at zero, or on the other side of zero from the range, now maps to the nearer end, meaning the end with the smaller magnitude. That is 0 for 20..20000, and 1 for a falling 20000..20 range.
  • NaN guard: a NaN shaped value maps to 0 before clamping, so the host always gets a position in [0, 1].
  • Construction: Linear, Skewed and Logarithmic reject min == max with ArgumentOutOfRangeException, as the triage suggested, so the misconfiguration shows up where it is made. WithCenter already rejected it. No caller in the repository builds a zero-width range.

Tests

The four new tests in AudioEngineeringTests all failed before the fix and pass after it:

  • log values at or below zero, on rising, falling and negative ranges
  • the decimal overflow case
  • NaN input
  • zero-width ranges for each factory

Full Semantics.Test on net10.0: 1484 passed, 8 skipped, 0 failed. The local Sonar build (.sonarlint/sonar-local.props) reports nothing on the changed file.

🤖 Generated with Claude Code

https://claude.ai/code/session_01A5MkmzQ4qxxRmHStdQ8oJA


Generated by Claude Code

…n values and reject empty ranges

Normalize relied on Math.Clamp, which passes NaN through, so a value at or below
zero on a logarithmic range returned NaN for double and threw OverflowException for
decimal. Such a value now maps to the nearer end (the one with the smaller
magnitude), and any remaining NaN maps to 0. Linear, Skewed and Logarithmic now
reject min == max, which used to reach the same NaN path.

Fixes #319

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

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

Development

Successfully merging this pull request may close these issues.

NormalizedParameter.Normalize returns NaN, not a clamped 0..1 value, for a log-range value ≤ 0 or a zero-width linear range (decimal throws)

2 participants