Summary
Port Python's fractions.Fraction to Rust — arbitrary-precision rational number arithmetic.
In CPython, this is a pure Python implementation (Lib/fractions.py) that internally stores a (numerator: int, denominator: int) pair, GCD-normalized with a positive denominator.
Design
Type representation
pub struct Fraction<I> {
numerator: I,
denominator: I, // always positive, coprime with numerator
}
Follow the existing _bigint feature pattern to support both num-bigint and malachite-bigint. Implement as generic over integer type or via trait bounds.
Feature flag
[features]
fractions = ["_bigint"] # requires BigInt
Same pattern as cmath behind the complex feature.
Implementation plan
Phase 1: Core struct & construction
Fraction struct (numerator, denominator)
- GCD normalization (sign normalization included: denominator always positive)
new(numerator, denominator) — primary constructor
from_integer(n) — construct from integer
from_float(f64) — using f64::integer_decode() or as_integer_ratio logic
from_coprime_ints(n, d) — direct construction from pre-normalized values (internal use)
- String parsing:
"3/4", "1.5", "1e-2", etc.
Phase 2: Arithmetic operations
Add, Sub, Mul, Div (Rust traits)
Neg, Abs
- Floor division, modulo, divmod
Pow — integer exponent returns Fraction / non-integer returns f64
Arithmetic optimization: Knuth TAOCP 4.5.1 approach (pre-compute GCD in multiplication to avoid unnecessary blowup)
Phase 3: Comparison & conversion
Eq, Ord (cross-multiply comparison)
as_f64() — float conversion
trunc(), floor(), ceil(), round() — integer conversions
is_integer() — checks denominator == 1
as_integer_ratio() — returns (numerator, denominator) tuple
Phase 4: Special methods
limit_denominator(max_denominator) — best rational approximation via continued fraction algorithm
- Hash: compatible with Python's
_hash_algorithm (modular inverse based)
- Display:
"{numerator}/{denominator}" or "{numerator}" when integer
- Format: float-style formatting (
.2f, e, g, etc.)
Phase 5: Testing
- Use the existing pyo3 proptest pattern from the project
- Verify bit-identical results against
fractions.Fraction
- Edge cases: zero, negatives, very large numbers, float precision boundary values
Out of scope
- Python
numbers.Rational ABC (replaced by Rust traits)
- Direct conversion with
Decimal type (separate module scope)
- Pickle/copy (Python runtime dependent)
References
Summary
Port Python's
fractions.Fractionto Rust — arbitrary-precision rational number arithmetic.In CPython, this is a pure Python implementation (
Lib/fractions.py) that internally stores a(numerator: int, denominator: int)pair, GCD-normalized with a positive denominator.Design
Type representation
Follow the existing
_bigintfeature pattern to support bothnum-bigintandmalachite-bigint. Implement as generic over integer type or via trait bounds.Feature flag
Same pattern as
cmathbehind thecomplexfeature.Implementation plan
Phase 1: Core struct & construction
Fractionstruct (numerator, denominator)new(numerator, denominator)— primary constructorfrom_integer(n)— construct from integerfrom_float(f64)— usingf64::integer_decode()oras_integer_ratiologicfrom_coprime_ints(n, d)— direct construction from pre-normalized values (internal use)"3/4","1.5","1e-2", etc.Phase 2: Arithmetic operations
Add,Sub,Mul,Div(Rust traits)Neg,AbsPow— integer exponent returns Fraction / non-integer returns f64Arithmetic optimization: Knuth TAOCP 4.5.1 approach (pre-compute GCD in multiplication to avoid unnecessary blowup)
Phase 3: Comparison & conversion
Eq,Ord(cross-multiply comparison)as_f64()— float conversiontrunc(),floor(),ceil(),round()— integer conversionsis_integer()— checks denominator == 1as_integer_ratio()— returns (numerator, denominator) tuplePhase 4: Special methods
limit_denominator(max_denominator)— best rational approximation via continued fraction algorithm_hash_algorithm(modular inverse based)"{numerator}/{denominator}"or"{numerator}"when integer.2f,e,g, etc.)Phase 5: Testing
fractions.FractionOut of scope
numbers.RationalABC (replaced by Rust traits)Decimaltype (separate module scope)References
Lib/fractions.py