Bonjour,
Les fractions sont définies ici avec des entiers de 64 bits.
On s'arrange pour que le dénominateur soit toujours positif.
Cas particulier: fraction indéfinie ↔ dénominateur = 0.
Les erreurs de division par zéro sont traitées, mais attention: pas celles de débordement (without run-time overflow checking) !
Fonctions développées (avec A, B: fractions; N, D, I: entiers):
Constructeur (avec simplification):
Frac(N, D)
Opérations unaires:
+A, -A
Affectations:
+= B, -= B, *= B, /= B
Opérations arithmétiques:
A + B, A - B, A * B, A / B
A + I, A - I, A * I, A / I
I + A, I - A, I * A, I / A
La simple structure
struct est utilisée pour faciliter la transcription du code dans d'autres langages de programmation:
#define llint long long int
struct Frac {
llint num, den; // den >= 0; indéfini: den = 0;
Frac() {num = 1; den = 0;} // constructor (indéfini)
Frac(llint n, llint d) {Set(n, d);} // constructor
Frac& operator += (const Frac& B)
{Set(num*B.den + den*B.num, den*B.den); return *this;}
Frac& operator -= (const Frac& B)
{Set(num*B.den - den*B.num, den*B.den); return *this;}
Frac& operator *= (const Frac& B)
{Set(num*B.num, den*B.den); return *this;}
Frac& operator /= (const Frac& B)
{Set(num*B.den, den*B.num); return *this;}
void Set(llint n, llint d) { // avec simplification
if (d < 0) {n = -n; d = -d;}
llint r = std::abs(n), s = d, t;
if (s != 0) { // r = pgcd(r, s)
do {t = r%s; r = s; s = t;} while (s > 0);
} else r = 1;
num = n/r; den = d/r;
}
};
bool operator == (const Frac& A, const Frac& B)
{return A.num*B.den == A.den*B.num;}
bool operator != (const Frac& A, const Frac& B)
{return A.num*B.den != A.den*B.num;}
bool operator < (const Frac& A, const Frac& B)
{return A.num*B.den < A.den*B.num;}
bool operator > (const Frac& A, const Frac& B)
{return A.num*B.den > A.den*B.num;}
bool operator <= (const Frac& A, const Frac& B)
{return A.num*B.den <= A.den*B.num;}
bool operator >= (const Frac& A, const Frac& B)
{return A.num*B.den >= A.den*B.num;}
Frac operator + (Frac A) {return A;}
Frac operator + (Frac A, const Frac& B) {return A += B;}
Frac operator + (Frac A, llint I) {A.num += I*A.den; return A;}
Frac operator + (llint I, Frac A) {A.num += I*A.den; return A;}
Frac operator - (Frac A) {A.num = -A.num; return A;}
Frac operator - (Frac A, const Frac& B) {return A -= B;}
Frac operator - (Frac A, llint I) {A.num -= A.den*I; return A;}
Frac operator - (llint I, Frac A) {A.num -= I*A.den; return A;}
Frac operator * (Frac A, const Frac& B) {return A *= B;}
Frac operator * (Frac A, llint I) {A.Set(A.num*I, A.den); return A;}
Frac operator * (llint I, Frac A) {A.Set(I*A.num, A.den); return A;}
Frac operator / (Frac A, const Frac& B) {return A /= B;}
Frac operator / (Frac A, llint I) {A.Set(A.num, A.den*I); return A;}
Frac operator / (llint I, Frac A) {A.Set(I*A.den, A.num); return A;}
Pour en faire une "library" (bibliothèque logicielle), il vaut mieux utiliser une structure plus "complète", c'est-à-dire avec des
protections.
Les tests dans
Fractions.cpp du
Zip montrent qu'on peut écrire des combinaisons d'opérations arithmétiques en mélangeant entiers et fractions.
A = Frac(37961, 60639) = [77/123] = 0.626016
B = Frac(460, -2185) = [-4/19] = -0.210526
Frac C; C = [INDEFINI] = inf
+A = [77/123] = 0.626016
-A = [-77/123] = -0.626016
A+B = [971/2337] = 0.41549
A-B = [1955/2337] = 0.836543
A-A = [0/1] = 0
2*A + 7*B = [-518/2337] = -0.221652 =? -0.221652
2*(A-1) - (B+3-A)*5 = [-27028/2337] = -11.5653 =? -11.5653
Fraction continue: C = [5/2] = 2.5
C = 2 + 1/C = [12/5] = 2.4
C = 2 + 1/C = [29/12] = 2.41667
C = 2 + 1/C = [70/29] = 2.41379
C = 2 + 1/C = [169/70] = 2.41429
C = 2 + 1/C = [408/169] = 2.4142
C = 2 + 1/C = [985/408] = 2.41422
C = 2 + 1/C = [2378/985] = 2.41421
C = 2 + 1/C = [5741/2378] = 2.41421
C = 2 + 1/C = [13860/5741] = 2.41421
C = 2 + 1/C = [33461/13860] = 2.41421
C = 1 + 1/C = [47321/33461] = 1.41421
Les fonctions
Val et
Out y sont utilisés pour "vérifier" les calculs.
Le dernier exemple correspond à la
fraction continue qui s'approche de √2:
1
√2 = 1 + ───────────────
1
2 + ───────────
1
2 + ───────
2 + ...
Bonne lecture ...
Liens
WikipédiA: Fraction (mathématiques)
WikipédiA: Fraction continue
CodeS-SourceS: Fractions, addition, soustraction, multiplication, division et simplification
GitHub: FractionCPP
GitHub: C++ Rational Number Class
Vous n'êtes pas encore membre ?
inscrivez-vous, c'est gratuit et ça prend moins d'une minute !
Les membres obtiennent plus de réponses que les utilisateurs anonymes.
Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.
Le fait d'être membre vous permet d'avoir des options supplémentaires.