Numerica 0.1.0-ci.1
dotnet add package Numerica --version 0.1.0-ci.1
NuGet\Install-Package Numerica -Version 0.1.0-ci.1
<PackageReference Include="Numerica" Version="0.1.0-ci.1" />
<PackageVersion Include="Numerica" Version="0.1.0-ci.1" />
<PackageReference Include="Numerica" />
paket add Numerica --version 0.1.0-ci.1
#r "nuget: Numerica, 0.1.0-ci.1"
#:package Numerica@0.1.0-ci.1
#addin nuget:?package=Numerica&version=0.1.0-ci.1&prerelease
#tool nuget:?package=Numerica&version=0.1.0-ci.1&prerelease
Numerica
Exact, lazy, expression-backed numbers for .NET — built from a formula string,
evaluated only when asked, behind a single public type (Numeric) that implements
INumber<T>.
A small C# project about exact numbers, built as a tower:
BigInteger -> BigRational -> BigIrrational -> BigComplex
(exact) (exact ==) (symbolic tree) (complex)
Numeric (front door: build from a formula string, evaluate lazily,
INumber<T>; == and < exact & decidable for algebraic formulas)
It starts from a real question — C# has BigInteger, why not a BigFloat? — and
follows the answer all the way to closed-form reals. The full reasoning and the
relevant papers are in DOCS.md.
Under the hood
Numeric (below) is the only public type — everything in this section is
internal, the machinery it drives.
BigRational— exactnum/denin lowest terms. Closed under+ - * /and integer powers, so==is genuinely exact:1/3 + 1/6is exactly1/2.BigIrrational— a rational pair cannot capturesqrt(2)(an irrational is, by definition, not a ratio of integers). So we store the operation, not a value: an exact symbolic tree of sums, products and powers with rational exponents, pluspi,eand the transcendental functionsexp,ln,sin,cos,tan,atan. Smart constructors simplify as they build, so identities cancel symbolically (sqrt(2)*sqrt(2) -> 2,phi^2 - phi - 1 -> 0). The value is materialized only on demand:Approximate(bits)returns a rational within2^-bits.BigComplex— real and imaginary parts are each aBigIrrational, so identities stay exact (i^2 = -1,|3+4i| = 5) and the usual complex functions (Exp,Ln,Sin,Cos,Sqrt, powers) are available — including Euler'sexp(i*pi) + 1 = 0.
There is also a decidable middle ground — algebraic numbers (roots of integer
polynomials), represented as a squarefree annihilating polynomial + an isolating
rational interval, where == and < are exact and decidable. That engine is
internal (Parsing/AlgebraicReal); you reach it through Numeric (below), whose
comparisons it makes exact for algebraic formulas. pi and e (transcendental) do
not live there.
Numeric — the front door
Numeric is the type you reach for first. You build it from a formula string;
it stays a suspended calculation (it holds the expression tree) and only becomes a
value when asked. It implements .NET's generic-math INumber<Numeric>, so it drops
into standard operators and algorithms, and converts to whichever level fits:
var n = new Numeric("sqrt(2) * sqrt(2)");
n.ToDecimalString(30); // "2.000000000000000000000000000000"
n.IsRational; // true (decided exactly: the value is 2)
n.IsIrrational; // false
n.IsComplex; // false
new Numeric("2 + 3*i").IsComplex; // true
new Numeric("(1 + sqrt(5)) / 2").IsIrrational; // true
new Numeric("sqrt(2)") < new Numeric("sqrt(3)"); // true
Numeric total = Numeric.One + new Numeric("1/2"); // composes via INumber<T>
IsRational / IsIrrational / IsComplex are the public way to ask what kind of
number you have. (The concrete BigRational / BigIrrational / BigComplex values
stay internal.)
== and < are exact and decidable when both formulas are algebraic
(rationals, + - * /, integer powers, roots of rationals): the comparison drops to
an internal minimal-polynomial + isolating-interval engine, so sqrt(2)*sqrt(2) == 2
is decided true. For transcendental formulas (pi, e, exp, ln, trig), where
exact equality is undecidable, it falls back to a high-precision numeric comparison.
One tree, three levels, parsed from strings
Expr is a single expression tree that evaluates at all three value levels —
ToRational(), ToIrrational(), ToComplex() — and strings map to it
automatically via Sprache:
Expr.Parse("1/3 + 1/6").ToRational(); // 1/2
Expr.Parse("sqrt(2) * sqrt(2)").ToIrrational(); // "2"
Expr.Parse("exp(i*pi) + 1").ToComplex(); // ~ 0
The theoretical limit
Exact == on closed-form reals is undecidable (Richardson's theorem): if two
values were equal, a bit-by-bit comparison would never terminate. So:
BigRationalhas exact, decidable equality, andNumericextends that to all algebraic formulas (via the internalAlgebraicRealengine).BigIrrational's simplifier reaches exact answers when the structure cancels; otherwise it compares only up to a chosen precision (CompareApprox/ApproximatelyEquals).
Running
Requires the .NET 10 SDK or later.
dotnet test # the regression suite (xUnit)
dotnet run --project SAMPLES/Numerica.BasicSample
Layout
Numerica/Numeric.cs— the front-door type (formula string, lazy,INumber<Numeric>)BigRational.cs— exact rationals (the floor of the tower)BigIrrational.cs— the symbolic tree + the numeric engineBigComplex.cs— complex numbers overBigIrrationalParsing/Expr.cs— the universal expression tree (three evaluators)ExpressionParser.cs— the Sprache grammar (string → tree)AlgebraicReal.cs— internal algebraic-number engine (decidable==/<)Polynomial.cs— rational-coefficient polynomials + Sturm machineryRealMath.cs— fixed-point exp / ln / sin / cos / atan
SAMPLES/Numerica.BasicSample/— a shortNumericdemoTEST/Numerica.Tests/— the xUnit regression suiteDOCS/DOCS.md— design notes and references to the relevant papers
Documentation
- Expression language reference — every operator, function, constant and literal form you can put in a formula string.
- Design notes & references — the theory and the papers behind it.
- Roadmap — where this could go next.
Contributing
Contributions are welcome — see CONTRIBUTING.md. Bug reports and ideas go through the GitHub issue templates.
License
MIT.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net10.0
- Sprache (>= 2.3.1)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 0.1.0-ci.1 | 97 | 6/9/2026 |