edutecnica

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.