What's wrong
Vector0Guards.EnsureNonNegative and EnsurePositive (Semantics.Quantities/Vector0Guards.cs around lines 34 and 60) test the value with T.Sign(value). For double, float and Half, Sign(NaN) throws ArithmeticException ("Function does not accept floating point Not-a-Number values."), so the documented ArgumentException is never reached.
Repro
Speed<double>.FromMeterPerSecond(double.NaN), Mass<double>.FromKilogram(double.NaN) and Wavelength<double>.FromMeter(double.NaN) all throw ArithmeticException.
Why it matters
Four places say this should be an ArgumentException:
- the guard XML docs;
- every generated factory's XML (for example
Speed.g.cs around line 101), which documents only ArgumentException;
- the Quantities docs;
- CLAUDE.md ("Throw
ArgumentException for validation failures").
A caller that validates user input by catching ArgumentException gets an unhandled ArithmeticException instead. #285's suggested fix routes scalar * and / through these guards, which would spread the same exception to arithmetic results such as 0 * ∞.
Suggested fix
In both guards, check T.IsNaN(value) first and throw ArgumentException($"Magnitude must be a number; received NaN.", paramName). Then compare with value < T.Zero / value <= T.Zero rather than T.Sign.
Acceptance: add tests for both guards with double.NaN, float.NaN and Half.NaN that assert ArgumentException, plus a generated-factory test such as Speed<double>.FromMeterPerSecond(double.NaN).
What's wrong
Vector0Guards.EnsureNonNegativeandEnsurePositive(Semantics.Quantities/Vector0Guards.csaround lines 34 and 60) test the value withT.Sign(value). Fordouble,floatandHalf,Sign(NaN)throwsArithmeticException("Function does not accept floating point Not-a-Number values."), so the documentedArgumentExceptionis never reached.Repro
Speed<double>.FromMeterPerSecond(double.NaN),Mass<double>.FromKilogram(double.NaN)andWavelength<double>.FromMeter(double.NaN)all throwArithmeticException.Why it matters
Four places say this should be an
ArgumentException:Speed.g.csaround line 101), which documents onlyArgumentException;ArgumentExceptionfor validation failures").A caller that validates user input by catching
ArgumentExceptiongets an unhandledArithmeticExceptioninstead. #285's suggested fix routes scalar*and/through these guards, which would spread the same exception to arithmetic results such as0 * ∞.Suggested fix
In both guards, check
T.IsNaN(value)first and throwArgumentException($"Magnitude must be a number; received NaN.", paramName). Then compare withvalue < T.Zero/value <= T.Zerorather thanT.Sign.Acceptance: add tests for both guards with
double.NaN,float.NaNandHalf.NaNthat assertArgumentException, plus a generated-factory test such asSpeed<double>.FromMeterPerSecond(double.NaN).