RustPython / RustPython/pymath

Add fractions module: Rational number arithmetic

Ouverte
#16 0 commentaires 0 réactions 0 personnes assignées Voir sur GitHub

Personne n'a encore pris cette issue.

Langage dominant
Rust
Étoiles
12
Forks
1
Merge moyen
8 min
PR mergées (30 j)
1

Description

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

Guide de contribution

Aucun guide de contribution indexé pour ce dépôt

Par où commencer

  1. Lisez l'issue en entier, puis le guide de contribution du projet.
  2. Signalez en commentaire que vous la prenez — cela évite que deux personnes fassent le même travail.
  3. Forkez le dépôt et travaillez sur une branche.
  4. Ouvrez une pull request qui référence le numéro de l'issue.

Piste de recherche

Commencez par lire Lib/fractions.py de CPython et le modèle de feature _bigint existant du projet, y compris cmath derrière la feature complex. Examinez le modèle proptest de pyo3 avant de définir l’API et le comportement par étapes. C’est terminé lorsque la feature fractions prend en charge les tests répertoriés de construction, d’arithmétique, de conversion, de formatage et de cas limites avec fractions.Fraction.

Rédigé par le modèle d'indexation à partir du texte de l'issue.

Évaluation

Stack technique
python, rust
Domaine
backend
Type d'issue
Fonctionnalité
Difficulté
5/5
Temps estimé
Plus d'une semaine
Activité
À l'abandon
Clarté
Plutôt claire
Accessibilité débutants
25/100

Recevez les nouvelles issues par e-mail

Un résumé court des issues GitHub adaptées aux débutants.