Esercizio 2
Implementa la classe "Razionale" idonea alla manipolazione di numeri razionali.
La classe deve poter sommare, sottrarre, moltiplicare e dividere numeri razionali esternalizzando il risultato.
La classe deve poter semplificare automaticamente una frazione riducendola ai minimi termini
e deve contenere un metodo che permetta la visualizzazione della frazione nella notazione
numeratore/denominatore.
#include <iostream>
#include <stdlib.h>
using namespace std;
class Razionale {
private:
int num,denom,segno;
int mcd(int a,int b){
return b==0 ? a : mcd(b,a%b);
}
public:
Razionale(int n){//costruttore 1
num=n;
denom=1;
}
Razionale(int n, int d){//costruttore 2
int segno=1;
if(n*d<0)segno=-1;
num=abs(n);
denom=abs(d);
int c=mcd(num,denom);
num=segno*num/c;//riduzione ai
denom=denom/c;//minimi termini
}//fine costruttore
int getNum(){return num;}
int getDen(){return denom;}
Razionale sum(Razionale s){
return Razionale(num*s.denom+denom*s.num,denom*s.denom);
}
Razionale dif(Razionale s){
return Razionale(num*s.denom-denom*s.num,denom*s.denom);
}
Razionale pro(Razionale s){
return Razionale(num*s.num,denom*s.denom);
}
Razionale div(Razionale s){
return Razionale(num*s.denom,denom*s.num);
}
string toString(){
char buffer [10];
string st=itoa (num,buffer,10);
st=st+"/"+itoa (denom,buffer,10);
return st;
}//fine toString()
};//fine classe razionale
main(){
Razionale h(3,-2);
Razionale k(2,5);
cout<<h.toString()<<endl;//stampa -3/2
cout<<h.sum(k).toString();//stampa -3/2+2/5=-11/10
}//__________fine main
La visualizzazione del risultato è dato dal metodo pubblico toString()
che utilizzando la funzione itoa() (un po' obsoleta)
restituisce una stringa della frazione nella notazione richiesta.
La semplificazione della frazione ai minimi termini avviene automaticamente,
dividendo numeratore e denominatore per il loro mcd. mcd()
è un metodo privato che implementa l'algoritmo di euclide in forma ricorsiva
per il calcolo del massimo comun divisore; sappiamo infatti che per semplificare
una frazione è sufficiente dividere numeratore e denominatore per
il loro massimo comun divisore.
La divisione per zero può essere evitata introducendo un blocco try-catch per la
gestione delle eccezioni nel secondo costruttore come
qui sotto riportato:
Razionale(int n, int d){//costruttore
2
string divByZero="divisione per zero";
try{
if(d==0) throw divByZero;
int segno=1;
if(n*d<0)segno=-1;
num=abs(n);
denom=abs(d);
int c=mcd(num,denom);
num=segno*num/c;//riduzione ai
denom=denom/c;//minimi termini
}catch(string &msg){
cerr<<msg<<endl;
}
}//fine costruttore
Lasciamo al lettore il compito di implementare un metodo che consenta di sapere se la frazione è propria o impropria e un metodo per confontare tra loro due frazioni per individuare la maggiore e la minore.