What's wrong
In Semantics.SourceGenerators/Metadata/units.json (around line 199), Milliliter is defined only as "magnitude": "Milli", with no conversion factor:
{ "name": "Milliliter", "symbol": "mL", "system": "SIDerived", "magnitude": "Milli" }
UnitsGenerator.BuildToBaseFactorExpression applies the magnitude to the dimension's SI base unit. For Volume that base unit is m³, not the litre, so the generated ToBaseFactor is MetricMagnitudes.Milli = 1e-3 m³. That is one litre. The correct factor is 1e-6 m³.
The same pattern gives correct results elsewhere only because those units are prefixed forms of the base unit itself. For example, Gram = Milli × kg = 1e-3 kg is correct, and Millimeter = Milli × m is correct. The litre is not the base unit of Volume, so the prefix alone is wrong here.
Failure scenario
Volume<double>.FromMilliliter(1.0).Value returns 0.001 (m³). It should return 1e-6.
- Everything that goes through the unit's factor is off by 1000×:
Capacity.FromMilliliter, IUnit.ToBaseFactor, ToBaseFactorAs<T>(), and every In(new Milliliter()).
For example, 5 mL of a dose or reagent comes out as 5 L. No test references Milliliter, so nothing catches this.
Suggested fix
Give the unit both parts:
"magnitude": "Milli",
"conversionFactor": "LiterToCubicMeters"
BuildToBaseFactorExpression already handles magnitude × factor, which produces 1e-3 × 1e-3 = 1e-6. Then regenerate.
Acceptance criteria
Volume<double>.FromMilliliter(1000).In(new Liter()) equals 1 (within tolerance).
Volume<double>.FromMilliliter(1).Value equals 1e-6 m³.
- Check the other units in
units.json that carry a magnitude in dimensions whose base unit is not the unprefixed form of that unit. Any new ones found get the same treatment and a test.
What's wrong
In
Semantics.SourceGenerators/Metadata/units.json(around line 199),Milliliteris defined only as"magnitude": "Milli", with no conversion factor:{ "name": "Milliliter", "symbol": "mL", "system": "SIDerived", "magnitude": "Milli" }UnitsGenerator.BuildToBaseFactorExpressionapplies the magnitude to the dimension's SI base unit. For Volume that base unit is m³, not the litre, so the generatedToBaseFactorisMetricMagnitudes.Milli= 1e-3 m³. That is one litre. The correct factor is 1e-6 m³.The same pattern gives correct results elsewhere only because those units are prefixed forms of the base unit itself. For example,
Gram= Milli × kg = 1e-3 kg is correct, andMillimeter= Milli × m is correct. The litre is not the base unit of Volume, so the prefix alone is wrong here.Failure scenario
Volume<double>.FromMilliliter(1.0).Valuereturns0.001(m³). It should return1e-6.Capacity.FromMilliliter,IUnit.ToBaseFactor,ToBaseFactorAs<T>(), and everyIn(new Milliliter()).For example, 5 mL of a dose or reagent comes out as 5 L. No test references
Milliliter, so nothing catches this.Suggested fix
Give the unit both parts:
BuildToBaseFactorExpressionalready handles magnitude × factor, which produces 1e-3 × 1e-3 = 1e-6. Then regenerate.Acceptance criteria
Volume<double>.FromMilliliter(1000).In(new Liter())equals 1 (within tolerance).Volume<double>.FromMilliliter(1).Valueequals 1e-6 m³.units.jsonthat carry amagnitudein dimensions whose base unit is not the unprefixed form of that unit. Any new ones found get the same treatment and a test.