Complesso
, anche per la classe Razionale
distribuiremo il codice in un file di intestazione (razionale.h
) e in
un file contenente le definizioni delle funzioni troppo elaborate per essere
definite all'interno della dichiarazione di classe (razionale.cpp
);
inoltre forniremo in coda un esempio di utilizzo della classe.
Si noti che anche in questo caso, siccome i campi dati della classe
Razionale
sono tutti non dinamici, si utilizzeranno il costruttore di
copia, l'operatore di assegnamento e il distruttore default.
// razionale.h // classe rappresentante un numero razionale #include <iostream.h> #include <math.h> class Razionale { public: Razionale (int Num = 0, int Den = 1); // Razionale (const Razionale&); // const Razionale& opetator= (const Razionale&); // ~Razionale(); // funzioni di accesso int numeratore() const { if (valido) return num; else return 0; } int denominatore() const { if (valido) return den; else return 0; } bool numeroValido() const { return valido; } int segno() const; void stampa() const; // operatori aritmetici Razionale operator- () const { // meno unario! if (valido == false) return Razionale(1,0); else return Razionale (-num, den); } Razionale operator+ (Razionale b) const; Razionale operator- (Razionale b) const { return *this + (-b); } Razionale operator* (Razionale b) const { return Razionale (num * b.num, den * b.den); } Razionale operator/ (Razionale b) const { return Razionale (num * b.den, den * b.num); } // operatori aritmetici & assegnamento Razionale& operator+= (Razionale b); Razionale& operator-= (Razionale b) { return (*this += -b); } Razionale& operator*= (Razionale b); Razionale& operator/= (Razionale b); Razionale& operator++ (int) { return (*this += 1); } Razionale& operator-- (int) { return (*this -= 1); } // operatori di confronto bool operator< (Razionale b) const; bool operator== (Razionale b) const; bool operator<= (Razionale b) const{ return (*this < b) || (*this == b); } bool operator!= (Razionale b) const { return !(*this == b); } bool operator> (Razionale b) const { return !(*this <= b); } bool operator>= (Razionale b) const{ return !(*this > b); } private: int num, den; // numeratore & denominatore bool valido; // flag: numero valido -> true // numero non valido -> false // funzioni per uso interno alla classe int max() const { // restituisce il maggiore tra num e den int Num = num * segno(); // Num e` positivo if (Num >= den) return Num; else return den; } int min() const { int Num = num * segno(); // Num e` positivo if (Num <= den) return Num; else return den; } void semplifica(); int mcd (int a, int b) const; int mcm (int a, int b) const { int m = (a * b) / mcd(a,b); return abs(m); } }; // overloading della funzione pow della libreria `math.h' Razionale pow (Razionale base, int esponente); double pow (Razionale base, double esponente); // razionale.cpp #include "razionale.h" Razionale::Razionale (int Num, int Den) { if (Den != 0) { // den deve essere positivo if (Den > 0) den = Den; else den = -Den; num = Num; valido = true; semplifica(); } else valido = false; // denominatore nullo } void Razionale::stampa() const { if (valido == false) cout << "nan"; // Not A Number: numero non valido else cout << num << '/' << den; } int Razionale::segno() const { if (num == 0) return 0; else if (num > 0) return 1; else return -1; } void Razionale::semplifica () { if (valido) { if (num != 0) { int m = mcd (num, den); num /= m; den /= m; } else den = 1; } } int Razionale::mcd (int a, int b) const { a = abs(a); b = abs(b); while (a != b) if (a > b) a -= b; else b -= a; return a; } Razionale Razionale::operator+ (Razionale b) const { if (valido == false || b.valido == false) return Razionale (1,0); int den_comune = mcm (den, b.den); int num_somma = (den_comune / den) * num + (den_comune / b.den) * b.num; return Razionale (num_somma, den_comune); } Razionale& Razionale::operator+= (Razionale b) { if (valido == false || b.valido == false) { *this = Razionale (1,0); return *this; } int den_comune = mcm (den, b.den); int num_somma = (den_comune / den) * num + (den_comune / b.den) * b.num; *this = Razionale (num_somma, den_comune); return *this; } Razionale& Razionale::operator*= (Razionale b) { if (valido == false || b.valido == false) { *this = Razionale (1,0); return *this; } num *= b.num; den *= b.den; semplifica(); return *this; } Razionale& Razionale::operator/= (Razionale b) { if (valido == false || b.valido == false) { *this = Razionale (1,0); return *this; } num *= b.den; den *= b.num; semplifica(); return *this; } bool Razionale::operator< (Razionale b) const { if (valido == false || b.valido == false) return false; double x = double(num) / double(den); double y = double(b.num) / double(b.den); if (x < y) return true; return false; } bool Razionale::operator== (Razionale b) const { if (valido == false || b.valido == false) return false; if (num == b.num && den == b.den) return true; else return false; } Razionale pow (Razionale base, int esponente) { if (base.numeroValido() == false) return Razionale (1,0); int num, den; if (esponente > 0) { num = pow (base.numeratore(), esponente); den = pow (base.denominatore(), esponente); } else if (esponente == 0) { num = 0; den = 1; } else { // esponente < 0 num = pow (base.denominatore(), -esponente); den = pow (base.numeratore(), -esponente); } return Razionale (num, den); } double pow (Razionale base, double esponente) { if (base.numeroValido() == false) return 0; double x = double(base.numeratore()) / double(base.denominatore()); return pow(x, esponente); }
Il programma di esempio è il seguente:
// ex9_7_2 #include "razionale.h" void main() { Razionale a(-5,7), b, c(60,-24), d(42,48), z(6,0); cout << "a: "; a.stampa(); cout << "\n"; cout << "b: "; b.stampa(); cout << "\n"; cout << "c: "; c.stampa(); cout << "\n"; cout << "d: "; d.stampa(); cout << "\n"; cout << "1/0: "; z.stampa(); cout << "\n"; z = -a; cout << "-a: "; z.stampa(); cout << "\n"; z = a + c; cout << "a+c: "; z.stampa(); cout << "\n"; z = a + 3; cout << "a+3: "; z.stampa(); cout << "\n"; z = a - c; cout << "a+c: "; z.stampa(); cout << "\n"; z = a - 2; cout << "a+c: "; z.stampa(); cout << "\n"; z = a * c; cout << "a*c: "; z.stampa(); cout << "\n"; z = a * 7; cout << "a*7: "; z.stampa(); cout << "\n"; z = a / c; cout << "a/c: "; z.stampa(); cout << "\n"; z = a / 5; cout << "a/5: "; z.stampa(); cout << "\n"; a += d; cout << "a+=d: "; a.stampa(); cout << "\n"; a++; cout << "a++: "; a.stampa(); cout << "\n"; a--; cout << "a--: "; a.stampa(); cout << "\n"; a -= d; cout << "a-=d: "; a.stampa(); cout << "\n"; a *= 3; cout << "a*=3: "; a.stampa(); cout << "\n"; a /= 6; cout << "a/=6: "; a.stampa(); cout << "\n"; z = pow(c, -2); cout << "pow(c,-2): "; z.stampa(); cout << "\n"; double x = pow (c, .5); cout << "pow(c,.5): "; cout << x << "\n"; }
output:
a: -5/7
b: 0/1
c: 5/2
d: 7/8
1/0: nan
-a: 5/7
a+c: 25/14
a+3: 16/7
a+c: -45/14
a+c: -19/7
a*c: -25/14
a*7: -5/1
a/c: -2/7
a/5: -1/7
a+=d: 9/56
a++: 65/56
a-: 9/56
a-=d: -5/7
a*=3: -15/7
a/=6: -5/14
pow(c,-2): 4/25
pow(c,.5): 1.58114
Come esercizio si consiglia di scrivere un programma che generi un array di numeri razionali, li ordini in senso crescente e li stampi.