ktsu.Semantics.Quantities.Precise
5.4.3
Prefix Reserved
See the version list below for details.
dotnet add package ktsu.Semantics.Quantities.Precise --version 5.4.3
NuGet\Install-Package ktsu.Semantics.Quantities.Precise -Version 5.4.3
<PackageReference Include="ktsu.Semantics.Quantities.Precise" Version="5.4.3" />
<PackageVersion Include="ktsu.Semantics.Quantities.Precise" Version="5.4.3" />
<PackageReference Include="ktsu.Semantics.Quantities.Precise" />
paket add ktsu.Semantics.Quantities.Precise --version 5.4.3
#r "nuget: ktsu.Semantics.Quantities.Precise, 5.4.3"
#:package ktsu.Semantics.Quantities.Precise@5.4.3
#addin nuget:?package=ktsu.Semantics.Quantities.Precise&version=5.4.3
#tool nuget:?package=ktsu.Semantics.Quantities.Precise&version=5.4.3
ktsu.Semantics.Quantities.Precise
Storage-type aliases that bind every
ktsu.Semantics.Quantitiestype toktsu.PreciseNumber.PreciseNumber, so you writeMassinstead ofMass<PreciseNumber>, project-wide.
ktsu.Semantics.Quantities.Precise is a satellite of ktsu.Semantics.Quantities in the ktsu.Semantics family. Read the core package README first for the quantity API itself.
Introduction
Every quantity in ktsu.Semantics.Quantities is generic over its numeric storage type, so you normally write Mass<PreciseNumber>, Speed<PreciseNumber>, and so on. If a project uses one storage type throughout, that generic argument is noise.
This package is props-only. It ships no assembly, just a build props file that injects one C# global-using alias per quantity, binding each open generic type to ktsu.PreciseNumber.PreciseNumber. Reference it and you can write Mass, Speed, Force3D with no generic argument, and every quantity resolves to its PreciseNumber form. The aliases are real Mass<PreciseNumber> (and so on), so they interoperate with the entire API with no conversion.
Installing this package also pulls in the matching version of ktsu.Semantics.Quantities and ktsu.PreciseNumber as dependencies, so it is the only reference you need. The core quantities package does not depend on ktsu.PreciseNumber; that dependency arrives only with this package.
Why this storage type
PreciseNumber is an arbitrary-precision type — a BigInteger significand with a decimal exponent — so a unit factor is applied at the precision the value carries rather than at the 15 to 17 significant digits a double holds. Conversions that terminate come out exact:
Length.FromFoot(PreciseNumber.One).In(Units.Inch) // exactly 12
1.0 * 0.3048 / 0.0254 // 12.000000000000002 in double
Roots are computed in the storage type's own arithmetic rather than through a double round trip, so a vector length keeps its digits too:
Velocity3D.One.Length() // 1.73205080756887729352744634150587236694280525381038
This costs speed and allocation against double, so it suits work where the error budget matters more than throughput — long-horizon integration, unit-conversion chains, and reference values to check a faster pipeline against.
Two limits worth knowing. The logarithmic scales (Decibels, Cents, PH, and the rest) still compute through double whatever the storage type. And a quotient that does not terminate is rounded to a precision derived from its operands, not carried forever.
Installation
Package Manager Console
Install-Package ktsu.Semantics.Quantities.Precise
.NET CLI
dotnet add package ktsu.Semantics.Quantities.Precise
Package Reference
<PackageReference Include="ktsu.Semantics.Quantities.Precise" Version="x.y.z" />
Usage Example
using ktsu.Semantics.Quantities; // types resolve to their PreciseNumber form via the injected aliases
using ktsu.PreciseNumber;
Mass mass = Mass.FromKilogram(10.ToPreciseNumber());
Speed speed = Speed.FromMeterPerSecond(15.ToPreciseNumber());
Mass total = mass + Mass.FromKilogram(2.ToPreciseNumber()); // still a Mass<PreciseNumber>, full identity
Force3D f = new() { X = 3.ToPreciseNumber(), Y = 4.ToPreciseNumber(), Z = PreciseNumber.Zero };
ForceMagnitude mag = f.Magnitude(); // exactly 5
Under the hood the injected alias looks like this (one line per quantity, roughly 220 in total):
<Using Include="ktsu.Semantics.Quantities.Mass<ktsu.PreciseNumber.PreciseNumber>" Alias="Mass" />
Use exactly one storage-type alias package per project
The aliases are project-wide global usings keyed on the bare type name (Mass, Speed, ...). Referencing two flavor packages in the same project would define the same alias name twice (one bound to PreciseNumber, one to another type), which is a compile error. So reference exactly one of:
ktsu.Semantics.Quantities.Doublektsu.Semantics.Quantities.Floatktsu.Semantics.Quantities.Decimalktsu.Semantics.Quantities.Precise(this package)
A project that genuinely needs mixed storage types should skip the alias packages and reference ktsu.Semantics.Quantities directly, writing the closed generic (Mass<PreciseNumber>) explicitly.
The binding applies to the project that declares the PackageReference, and to no other. The props
ship in the package's build/ folder rather than buildTransitive/, so they are not inherited by
projects that reference this project. An application assembled from several projects, each wrapping
a different storage type, therefore compiles: each project that wants aliases references its own alias
package, and no project collects a binding it never asked for. Earlier versions shipped the props in
buildTransitive/, where the binding did flow downstream and two of them in one dependency graph
produced a wall of CS1537 against a generated file the author never wrote; PrivateAssets="all" on
the alias reference was the workaround for that, and is no longer needed.
The alias lists are generated from the quantity catalogue by scripts/Generate-AliasProps.ps1 and validated in CI, so they stay in lockstep with the quantities the core package emits.
Contributing
Contributions are welcome! Feel free to open issues or submit pull requests.
License
This project is licensed under the MIT License. See the LICENSE.md file for details.
Learn more about Target Frameworks and .NET Standard.
-
net10.0
- ktsu.PreciseNumber (>= 2.0.3)
- ktsu.Semantics.Quantities (>= 5.4.3)
-
net8.0
- ktsu.PreciseNumber (>= 2.0.3)
- ktsu.Semantics.Quantities (>= 5.4.3)
-
net9.0
- ktsu.PreciseNumber (>= 2.0.3)
- ktsu.Semantics.Quantities (>= 5.4.3)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
## v5.4.3 (patch)
Changes since v5.4.2:
- Ship the storage-type alias props in build/, not buildTransitive/ [patch] ([@matt-edmondson](https://github.com/matt-edmondson))