/** La classe Rationnel represente un nombre rationnel mais sous forme 
  * normalisee (i.e. fraction la plus simple possible, et signe de la 
  * fraction sur le numerateur);
 */
public class Rationnel
{
    protected int numerateur;
    protected int denominateur;
    
    /** Cree un rationnel dont le numerateur est n et le denominateur est d.
      * La rationnel cree doit etre normalise (le signe doit etre sur le 
      * numerateur et la fraction ne doit plus pouvoir etre simplifiee).
      * @param n le numerateur
      * @param d le denominateur
     */
    public Rationnel(int n, int d)
    {
	if (d < 0) {
	    n = -n;
	    d = -d;
	}
	int p = pgcd(Math.abs(n), Math.abs(d));
	numerateur = n / p;
	denominateur = d /p;
    }
    
    /** Retourne le plus grand diviseur de deux nombres.
      * Dans l'ensemble des diviseurs communs a deux nombres entiers, il y en a 
      * un qui est le plus grand. Il est appele Plus Grand Commun Diviseur des 
      * deux nombres, ce qu'on note en abrege : PGCD.
      * On note PGCD (a ; b) le plus grand commun diviseur de a et b.
      * Exemple : Dans la liste des diviseurs communs de 60 et 72 : (1 ; 2 ; 3 ; 
      * 4 ; 6 ; 12), le plus grand est 12, on ecrit :
      * PGCD (72 ; 60) = 12.
      * 
      * @param a un entier
      * @param b un entier
      * @return le plus grand diviseur commun de a et b
     */
    public int pgcd(int a, int b)
    {
        if ((a < 0) || (b < 0)) {
		return -1;
	}
	int r = 0;
	while (b != 0) {
	    r = a % b;
	    a = b;
	    b = r;
	}
	return a;
    }
    
    /** Retourne le numerateur
      * @return le numerateur
     */
    public int getNumerateur()
    {
	return numerateur;
    }
    
    /** Retourne le denominateur
      * @return le denominateur
     */
    public int getDenominateur()
    {
	return(denominateur);
    }
    
    /** Affiche un rationnel
      * @return la chaine de caracteres representant le rationnel
     */
    public String toString()
    {
	return numerateur + "/" + denominateur;
    }
    
    /** Effectue la multiplication de deux rationnels.
      * @param r un rationnel
      * @return le rationnel representant la multiplication du rationnel courant avec r.
     */
    public Rationnel multiplication(Rationnel r)
    {
	return new Rationnel(this.numerateur * r.getNumerateur(),
			     this.denominateur * r.getDenominateur());
    }
    
    /** Calcul l'inverse du rationnel courant.
      * @return l'inverse du rationnel courant
     */
    public Rationnel inverse()
    {
	if (numerateur == 0) {
	    return null;
	} // En attendant de savoir creer une exception ...
	return new Rationnel(denominateur, numerateur);
    }
    
    /** Additionne deux rationnels.
      * @param r un rationnel
      * @return le rationnel representant la somme du rationel courant et de r
     */
    public Rationnel addition(Rationnel r)
    {
	return new Rationnel(numerateur * r.denominateur + r.numerateur * denominateur,
			     denominateur * r.denominateur);
    }

}

