puremp/lib.rs
1//! `puremp` — arbitrary-precision arithmetic written entirely in Rust, depending
2//! on no foreign code.
3//!
4//! It provides a family of numeric types, built bottom-up:
5//!
6//! 1. **Integers** — unsigned [`Nat`] and signed [`Int`], the workhorse layer
7//! that carries the hard limb-level algorithms (multiplication, division,
8//! GCD, modular arithmetic, …). Enabled by the `int` feature.
9//! 2. **Rationals** — [`Rational`], exact `p/q` fractions kept in lowest terms;
10//! plus [`InfRational`], the same extended with `±∞`/`NaN`. `rational` feature.
11//! 3. **Dyadics** — [`Dyadic`], exact `n·2^-k` binary fractions. `dyadic` feature.
12//! 4. **Floats** — [`Float`], binary floating-point with a caller-chosen
13//! precision and directed [`RoundingMode`], aiming at MPFR-class correct
14//! rounding, plus [`FixedFloat`], a fixed-precision wrapper with operators.
15//! `float` feature.
16//! 5. **Decimals** — [`Decimal`], exact base-10 floating point (Python
17//! `Decimal`-style), with directed rounding. `decimal` feature.
18//!
19//! Built on top of these are several *derived* structures, each generic or
20//! specialised as noted:
21//!
22//! - [`ModInt`] — modular integers `ℤ/mℤ` with automatic reduction (`int`).
23//! - [`Complex`] — generic complex numbers / Gaussian integers (`complex`).
24//! - [`GaloisField`] / [`GfElement`] — finite field extensions `GF(pᵏ)`
25//! (`galois`).
26//! - [`Poly`] — generic univariate polynomials (`poly`).
27//! - [`Matrix`] — dense matrices with exact determinant/inverse/solve
28//! (`matrix`).
29//!
30//! The generic [`Poly`]/[`Matrix`] containers work over any [`Ring`], an
31//! abstraction whose zero/one are taken relative to a sample element so that
32//! context-carrying rings ([`ModInt`], [`GfElement`]) can supply identities in
33//! their own modulus/field.
34//! - [`Interval`] — outward-rounded interval arithmetic (`interval`).
35//! - [`Ball`] — midpoint–radius (mid-rad) rigorous arithmetic, Arb-style (`ball`).
36//! - [`Padic`] — fixed-precision `p`-adic numbers in `ℚ_p` (`padic`).
37//! - [`Quadratic`] / [`Algebraic`] — exact quadratic irrationals `ℚ(√d)` and
38//! general real algebraic numbers (`algebraic`).
39//! - [`EllipticCurve`] / [`Point`] — elliptic curves `y² = x³ + a·x + b` over
40//! `GF(p)` or `ℚ`, with the chord-and-tangent group law (`elliptic`).
41//!
42//! `Int`/`Rational` also carry a number-theory toolkit (factorization,
43//! `sqrt_mod`, Jacobi/Legendre, CRT, `random_prime`, combinatorics,
44//! continued-fraction approximation), certificate-based primality *proving*
45//! ([`primality`], the `primality` feature), and an optional `num-traits` bridge
46//! slots the types into generic numeric code.
47//!
48//! `puremp` is usable as a Rust library, a C library (the `ffi` feature; see
49//! `include/puremp.h`), and a standalone command-line calculator (the `cli`
50//! feature; the `puremp` binary).
51//!
52//! This is a clean-room implementation: it is MIT-licensed and its algorithms
53//! are drawn from the open literature (Knuth; Brent & Zimmermann's *Modern
54//! Computer Arithmetic*; the HAC), never from GMP/MPFR source. See the README's
55//! "Design & provenance" section for the algorithm references.
56//!
57//! # Example
58//!
59//! ```
60//! use puremp::{Int, Rational};
61//!
62//! // Arbitrary-precision integers.
63//! let big = Int::from(2).pow(128);
64//! assert_eq!(big.to_string(), "340282366920938463463374607431768211456");
65//! assert_eq!(Int::from(1071).gcd(&Int::from(462)).to_string(), "21");
66//! assert_eq!(Int::from(2).modpow(&Int::from(10), &Int::from(1000)).to_string(), "24");
67//!
68//! // Exact rationals, always in lowest terms.
69//! let third = Rational::new(Int::from(1), Int::from(3));
70//! let sum = &(&third + &third) + &third;
71//! assert_eq!(sum.to_string(), "1");
72//! ```
73//!
74//! # `no_std`
75//!
76//! The crate is `#![no_std]` at its core. Arbitrary-precision types are
77//! heap-backed, so they need the `alloc` crate; the `alloc` feature (implied by
78//! every type layer) pulls it in. The `std` feature (enabled by default) adds
79//! the pieces that genuinely need the operating system — the CLI, `std::error`
80//! integration, and system I/O. Build with `--no-default-features` for a bare
81//! `no_std` target.
82
83#![no_std]
84
85#[cfg(feature = "alloc")]
86extern crate alloc;
87
88#[cfg(feature = "std")]
89extern crate std;
90
91pub mod error;
92
93pub mod ring;
94
95#[cfg(feature = "int")]
96mod limb;
97
98#[cfg(feature = "int")]
99pub mod int;
100#[cfg(feature = "int")]
101pub mod nat;
102
103#[cfg(feature = "int")]
104pub mod random;
105
106#[cfg(feature = "int")]
107mod ecm;
108
109#[cfg(feature = "int")]
110mod qsieve;
111
112#[cfg(feature = "num-traits")]
113mod num_traits_impls;
114
115#[cfg(feature = "rational")]
116pub mod rational;
117
118#[cfg(feature = "rational")]
119pub mod inf_rational;
120
121#[cfg(feature = "int")]
122pub mod mod_int;
123
124#[cfg(feature = "dyadic")]
125pub mod dyadic;
126
127#[cfg(feature = "padic")]
128pub mod padic;
129
130#[cfg(feature = "decimal")]
131pub mod decimal;
132
133#[cfg(feature = "complex")]
134pub mod complex;
135
136#[cfg(feature = "galois")]
137pub mod galois;
138
139#[cfg(feature = "poly")]
140pub mod poly;
141
142#[cfg(feature = "matrix")]
143pub mod matrix;
144
145#[cfg(all(feature = "poly", feature = "rational"))]
146mod poly_factor;
147
148#[cfg(all(feature = "poly", feature = "int"))]
149mod poly_finite_field;
150
151#[cfg(feature = "lattice")]
152pub mod lattice;
153
154#[cfg(feature = "identify")]
155pub mod identify;
156
157#[cfg(feature = "dlog")]
158pub mod dlog;
159
160#[cfg(feature = "primality")]
161pub mod primality;
162
163#[cfg(feature = "algebraic")]
164pub mod quadratic;
165
166#[cfg(feature = "algebraic")]
167pub mod algebraic;
168
169#[cfg(feature = "elliptic")]
170pub mod elliptic;
171
172#[cfg(feature = "float")]
173pub mod float;
174#[cfg(feature = "float")]
175mod float_consts;
176#[cfg(feature = "float")]
177mod float_mp;
178#[cfg(feature = "float")]
179mod float_mp_consts;
180
181#[cfg(feature = "float")]
182pub mod fixed_float;
183
184#[cfg(feature = "interval")]
185pub mod interval;
186
187#[cfg(feature = "ball")]
188pub mod ball;
189
190#[cfg(feature = "ball")]
191pub mod ball_solve;
192
193#[cfg(feature = "ffi")]
194pub mod ffi;
195
196#[cfg(feature = "serde")]
197mod serde_impls;
198
199pub use error::{Error, Result};
200
201pub use ring::{Field, Ring};
202
203#[cfg(feature = "int")]
204pub use ring::FiniteField;
205
206#[cfg(all(feature = "poly", feature = "int"))]
207pub use poly_finite_field::FactorOverField;
208
209#[cfg(feature = "int")]
210pub use int::{Int, Sign};
211#[cfg(feature = "int")]
212pub use nat::{Nat, Reciprocal, u_gcd, u64_gcd};
213#[cfg(feature = "int")]
214pub use random::{RandomSource, SeedRng};
215
216#[cfg(feature = "rational")]
217pub use inf_rational::InfRational;
218#[cfg(feature = "rational")]
219pub use rational::Rational;
220
221#[cfg(feature = "int")]
222pub use mod_int::ModInt;
223
224#[cfg(feature = "dyadic")]
225pub use dyadic::Dyadic;
226
227#[cfg(feature = "padic")]
228pub use padic::Padic;
229
230#[cfg(feature = "decimal")]
231pub use decimal::{Decimal, Rounding};
232
233#[cfg(feature = "complex")]
234pub use complex::Complex;
235
236#[cfg(feature = "galois")]
237pub use galois::{GaloisField, GfElement};
238
239#[cfg(feature = "poly")]
240pub use poly::Poly;
241
242#[cfg(feature = "matrix")]
243pub use matrix::{FieldMatrix, Matrix, RingMatrix};
244
245#[cfg(feature = "lattice")]
246pub use lattice::{lll_reduce, lll_reduce_delta};
247
248#[cfg(feature = "identify")]
249pub use identify::{Identification, identify, identify_with, machin_like};
250
251#[cfg(feature = "dlog")]
252pub use dlog::{bsgs, discrete_log, pohlig_hellman, pollard_rho};
253
254#[cfg(feature = "primality")]
255pub use primality::{Primality, PrimalityCertificate, prove_prime};
256
257#[cfg(feature = "algebraic")]
258pub use algebraic::Algebraic;
259#[cfg(feature = "algebraic")]
260pub use quadratic::Quadratic;
261
262#[cfg(feature = "elliptic")]
263pub use elliptic::{EllipticCurve, Point};
264
265#[cfg(feature = "float")]
266pub use fixed_float::FixedFloat;
267#[cfg(feature = "float")]
268pub use float::{Float, RoundingMode};
269
270#[cfg(feature = "ball")]
271pub use ball::Ball;
272#[cfg(feature = "ball")]
273pub use ball_solve::bisect_root;
274#[cfg(feature = "interval")]
275pub use interval::Interval;
276
277/// The crate version string (`CARGO_PKG_VERSION`), exposed for the C ABI and CLI.
278pub const VERSION: &str = env!("CARGO_PKG_VERSION");