non-negative.
lossy for magnitude/precision beyond what
Number can hold exactly — documented, not hidden.
canonical [-]digits(.digits)? form.
StaticfromBest-effort, explicitly lossy: a JS number is binary
floating-point, so its exact decimal expansion is used, which may
carry more (or differently rounded) digits than the value's
"intended" decimal literal had — the same lossiness
DXNDecimal#toNumber has, just in the other direction.
Staticfrom[-]digits(.digits)?, no M suffix (that's
.dxn text syntax, applied/stripped by the text codec, not here).
DXN
decimal([0-9]+(.[0-9]+)?M) — exact fixed-point, stored assign × unscaledValue × 10^exponent(unscaledValuea non-negativeBigInt,exponentthe scale). Hand-rolled rather than built on a decimal-arithmetic package (decimal.jset al.) to keep this project dependency-free, per its zero-runtime-dependency default — only parse/format/compare/equals are needed for v1, not full arithmetic.Equality/ordering compare
sign/unscaledValue/exponentdirectly (the generic field-reflection default fromequality.cjs), not normalized numeric value — mirrorsDXNRationalnever auto-reducing: two representations of the same numeric value at different scales (1.10vs1.1) are distinct DXN values, matching the "exact fixed-point" precisionDXN.mddescribes.