Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/Nonanti/mathcore/llms.txt

Use this file to discover all available pages before exploring further.

The mathcore::precision module provides lossless numerical computation through the PrecisionNumber enum, which unifies exact rational arithmetic (BigRational), arbitrary-precision integers (BigInt), and ordinary floating-point values (f64) under a single type. The companion ArbitraryPrecision struct computes mathematical constants such as π and e to user-specified precision using convergent rational series. The backing types BigInt and BigRational come from the num-bigint and num-rational crates respectively. Mixed-type arithmetic is handled by promoting both operands to BigRational before operating.

pub enum PrecisionNumber

The central type of the module. Holds a number in one of three precision representations.
#[derive(Debug, Clone)]
pub enum PrecisionNumber {
    /// Exact rational number p/q stored as a BigRational
    Exact(BigRational),
    /// IEEE-754 double-precision floating point
    Float(f64),
    /// Arbitrary-precision integer stored as a BigInt
    Integer(BigInt),
}
VariantBacking typeUse case
Exact(BigRational)num_rational::BigRationalRational arithmetic without rounding, e.g. 1/3 + 1/6 = 1/2 exactly.
Float(f64)f64Approximate values; used as a fallback when exact representation is unavailable.
Integer(BigInt)num_bigint::BigIntWhole numbers of any size, e.g. factorials, cryptographic primes.

from_f64

Constructs a PrecisionNumber from an f64. If the value is finite and has no fractional part, it is stored as Integer(BigInt). Otherwise it is stored as Float(f64).
pub fn from_f64(value: f64) -> PrecisionNumber
value
f64
required
The floating-point value to convert. Integral values such as 4.0 become Integer(4); fractional values such as 3.14 become Float(3.14).
use mathcore::precision::PrecisionNumber;

let n = PrecisionNumber::from_f64(42.0);
println!("{}", n); // 42

let f = PrecisionNumber::from_f64(3.14);
println!("{}", f); // 3.14

from_str_with_precision

Parses a string into a PrecisionNumber, preserving exactness where possible. The parsing rules are applied in order:
  1. Integer — if the string is a valid integer literal (e.g. "42", "-7"), returns Integer(BigInt).
  2. Rational — if the string contains a / (e.g. "3/4", "-1/7"), parses numerator and denominator and returns Exact(BigRational).
  3. Decimal — if the string contains a . (e.g. "2.5", "0.333"), converts the decimal to an exact rational (e.g. 25/10), returning Exact(BigRational).
  4. Float fallback — attempts str.parse::<f64>() and returns Float.
pub fn from_str_with_precision(s: &str) -> Result<PrecisionNumber, MathError>
s
&str
required
A string representation of the number. Supported formats: integer literals, "p/q" fraction notation, and decimal notation.
Returns Ok(PrecisionNumber) on success, or Err(MathError::ParseError) when the string cannot be parsed in any supported format.
use mathcore::precision::PrecisionNumber;

let one_third = PrecisionNumber::from_str_with_precision("1/3").unwrap();
println!("{}", one_third); // 1/3

let decimal = PrecisionNumber::from_str_with_precision("2.5").unwrap();
println!("{}", decimal); // 5/2  (exact rational)

let integer = PrecisionNumber::from_str_with_precision("100").unwrap();
println!("{}", integer); // 100

to_rational

Converts the PrecisionNumber to a BigRational. For Exact and Integer variants this is lossless. For Float, the conversion uses BigRational::from_float, falling back to BigRational::zero() for non-finite values.
pub fn to_rational(&self) -> BigRational
use mathcore::precision::PrecisionNumber;

let n = PrecisionNumber::from_str_with_precision("3/7").unwrap();
let r = n.to_rational();
println!("{}/{}", r.numer(), r.denom()); // 3/7

add

Adds two PrecisionNumber values, preserving the highest level of precision available:
  • Integer + IntegerInteger
  • Exact + ExactExact
  • Float + FloatFloat
  • Mixed types → both promoted to BigRational, result is Exact
pub fn add(&self, other: &PrecisionNumber) -> PrecisionNumber
other
&PrecisionNumber
required
The value to add to self.
use mathcore::precision::PrecisionNumber;

let a = PrecisionNumber::from_str_with_precision("1/3").unwrap();
let b = PrecisionNumber::from_str_with_precision("1/6").unwrap();
let sum = a.add(&b);
println!("{}", sum); // 1/2

subtract

Subtracts other from self using the same precision-preservation rules as add.
pub fn subtract(&self, other: &PrecisionNumber) -> PrecisionNumber
other
&PrecisionNumber
required
The value to subtract from self.

multiply

Multiplies two PrecisionNumber values with the same precision-preservation rules as add.
pub fn multiply(&self, other: &PrecisionNumber) -> PrecisionNumber
other
&PrecisionNumber
required
The multiplier.
use mathcore::precision::PrecisionNumber;

let a = PrecisionNumber::from_str_with_precision("2.5").unwrap();
let b = PrecisionNumber::from_str_with_precision("3.7").unwrap();
let product = a.multiply(&b);
println!("{}", product); // 925/100  (= 9.25 exactly)

divide

Divides self by other. Returns Err(MathError::DivisionByZero) when other is zero.
pub fn divide(&self, other: &PrecisionNumber) -> Result<PrecisionNumber, MathError>
other
&PrecisionNumber
required
The divisor. Must not be zero.
Returns Ok(PrecisionNumber) on success, or Err(MathError::DivisionByZero) when the divisor is zero.
use mathcore::precision::PrecisionNumber;

let a = PrecisionNumber::from_str_with_precision("7").unwrap();
let b = PrecisionNumber::from_str_with_precision("3").unwrap();
let result = a.divide(&b).unwrap();
println!("{}", result); // 7/3

// Division by zero
let zero = PrecisionNumber::from_f64(0.0);
assert!(a.divide(&zero).is_err());

factorial

Computes the factorial of a non-negative Integer value using exact BigInt arithmetic. Produces arbitrarily large results without overflow.
pub fn factorial(&self) -> Result<PrecisionNumber, MathError>
Returns Ok(PrecisionNumber::Integer(n!)) for non-negative integer inputs, or Err(MathError::InvalidOperation) for negative values or non-integer variants.
use mathcore::precision::PrecisionNumber;

let n = PrecisionNumber::from_str_with_precision("20").unwrap();
let fact = n.factorial().unwrap();
println!("{}", fact); // 2432902008176640000

is_zero

Returns true if the value represents zero. For Float, uses f64::EPSILON as the threshold.
pub fn is_zero(&self) -> bool

to_f64

Converts the PrecisionNumber to an Option<f64>. Returns None if the value cannot be represented as f64 (e.g. a BigInt too large for f64).
pub fn to_f64(&self) -> Option<f64>
Returns Some(f64) for values that can be approximated, or None when the conversion is not possible.
use mathcore::precision::PrecisionNumber;

let r = PrecisionNumber::from_str_with_precision("1/3").unwrap();
println!("{:.6}", r.to_f64().unwrap()); // 0.333333

power

Raises self to the power given by exponent. Integer exponentiation is computed exactly using BigInt::pow. Negative integer exponents produce an Exact(BigRational) result. All other combinations fall back to f64::powf and return Float.
pub fn power(&self, exponent: &PrecisionNumber) -> Result<PrecisionNumber, MathError>
exponent
&PrecisionNumber
required
The exponent. Negative Integer exponents are supported and produce an exact rational result.
Returns Ok(PrecisionNumber) with the result, or Err(MathError::InvalidOperation) when the exponent is too large to handle exactly as a u32.
use mathcore::precision::PrecisionNumber;

let base = PrecisionNumber::from_str_with_precision("2").unwrap();
let exp  = PrecisionNumber::from_str_with_precision("10").unwrap();
let result = base.power(&exp).unwrap();
println!("{}", result); // 1024

sqrt

Computes the square root of self. For non-negative Integer values the result is Integer when the square root is exact and Float otherwise. Float inputs use f64::sqrt. Exact(BigRational) inputs are converted to f64 before taking the root. Negative values return Err.
pub fn sqrt(&self) -> Result<PrecisionNumber, MathError>
Returns Ok(PrecisionNumber) containing the square root, or Err(MathError::InvalidOperation) for negative inputs, or Err(MathError::Overflow) when the integer value cannot be converted to f64.
use mathcore::precision::PrecisionNumber;

let n = PrecisionNumber::from_str_with_precision("9").unwrap();
let root = n.sqrt().unwrap();
println!("{}", root); // 3  (exact Integer)

let f = PrecisionNumber::from_f64(2.0);
let root2 = f.sqrt().unwrap();
println!("{:.6}", root2.to_f64().unwrap()); // 1.414214

pub struct ArbitraryPrecision

Computes mathematical constants to arbitrary precision using rational series. All results are returned as PrecisionNumber::Exact(BigRational).
pub struct ArbitraryPrecision;

compute_pi

Approximates π using the Bailey-Borwein-Plouffe (BBP) formula:
π = Σ_{k=0}^{precision-1}  (1/16^k) * (4/(8k+1) - 2/(8k+4) - 1/(8k+5) - 1/(8k+6))
The result is a PrecisionNumber::Exact(BigRational) whose accuracy improves with higher precision.
pub fn compute_pi(precision: usize) -> PrecisionNumber
precision
usize
required
Number of BBP series terms to sum. Each additional term roughly adds ~1.2 decimal digits of accuracy. A value of 50 gives roughly 60 correct decimal digits.
Returns PrecisionNumber::Exact(BigRational) approximating π.
use mathcore::precision::ArbitraryPrecision;

let pi_approx = ArbitraryPrecision::compute_pi(20);
println!("π ≈ {}", pi_approx);

// Convert to f64 for comparison
if let Some(f) = pi_approx.to_f64() {
    println!("π ≈ {:.15}", f); // ≈ 3.141592653589793
}

compute_e

Approximates Euler’s number e using the standard factorial series:
e = Σ_{n=0}^{precision-1}  1/n!
The result is a PrecisionNumber::Exact(BigRational) that converges rapidly — 20 terms yield about 18 correct decimal digits.
pub fn compute_e(precision: usize) -> PrecisionNumber
precision
usize
required
Number of terms to sum in the series 1 + 1/1! + 1/2! + .... Convergence is fast; precision = 30 gives more than 30 correct digits.
Returns PrecisionNumber::Exact(BigRational) approximating e.
use mathcore::precision::ArbitraryPrecision;

let e_approx = ArbitraryPrecision::compute_e(30);
println!("e ≈ {}", e_approx);

if let Some(f) = e_approx.to_f64() {
    println!("e ≈ {:.15}", f); // ≈ 2.718281828459045
}

compute_sqrt

Iteratively approximates the integer square root of a non-negative BigInt using the Babylonian (Heron’s) method. The iteration x ← (x + n/x) / 2 is repeated precision times. When the result squared equals n exactly, a PrecisionNumber::Integer is returned; otherwise the final BigInt approximation is returned as Integer. Negative inputs immediately return PrecisionNumber::Float(f64::NAN).
pub fn compute_sqrt(n: &BigInt, precision: usize) -> PrecisionNumber
n
&BigInt
required
The non-negative integer whose square root is to be approximated. Negative values produce PrecisionNumber::Float(NAN).
precision
usize
required
Number of Babylonian iterations to perform. More iterations converge closer to the true integer square root.
Returns PrecisionNumber::Integer containing the approximate (or exact) integer square root, or PrecisionNumber::Float(f64::NAN) for negative input.
use mathcore::precision::ArbitraryPrecision;
use num_bigint::BigInt;

// Exact: √144 = 12
let n = BigInt::from(144u32);
let root = ArbitraryPrecision::compute_sqrt(&n, 20);
println!("{}", root); // 12

// Approximate: √2 ≈ 1 (integer approximation)
let two = BigInt::from(2u32);
let root2 = ArbitraryPrecision::compute_sqrt(&two, 50);
println!("{}", root2); // 1  (integer floor of √2)

Complete example

use mathcore::precision::{ArbitraryPrecision, PrecisionNumber};

fn main() {
    // Exact rational arithmetic: 1/3 + 1/6 = 1/2
    let a = PrecisionNumber::from_str_with_precision("1/3").unwrap();
    let b = PrecisionNumber::from_str_with_precision("1/6").unwrap();
    let sum = a.add(&b);
    println!("1/3 + 1/6 = {}", sum); // 1/2

    // Factorial of 20 (exact integer, no overflow)
    let n = PrecisionNumber::from_str_with_precision("20").unwrap();
    let fact = n.factorial().unwrap();
    println!("20! = {}", fact); // 2432902008176640000

    // High-precision π
    let pi = ArbitraryPrecision::compute_pi(50);
    println!("π  = {}", pi);

    // High-precision e
    let e = ArbitraryPrecision::compute_e(50);
    println!("e  = {}", e);

    // Mixed-type arithmetic promotes to Exact
    let int_val  = PrecisionNumber::from_str_with_precision("7").unwrap();
    let rat_val  = PrecisionNumber::from_str_with_precision("1/3").unwrap();
    let mixed    = int_val.add(&rat_val);
    println!("7 + 1/3 = {}", mixed); // 22/3
}

Build docs developers (and LLMs) love