/**
	Classe per rappresentare e manipolare numeri razionali.
	Realizzata durante la lezione del 13 Novembre 2002
	@author Studenti turno di laboratorio 3
	@version 2.0
*/
import java.math.*;

public class Rational
{
	/**
   	Produce il numero razionale il cui numeratore e' rappresentato dalla
   	stringa decimale (con segno opzionale) n e il cui denominatore e'
   	rappresentato dalla stringa decimale (senza segno) ma maggiore di 0, d.
		@throws NumberFormatException - se n/d non e'un valido rappresentante
		di un BigInteger
	*/
	public Rational(String n, String d)
	{
		numerator = Integer.parseInt(n);
		denominator = Integer.parseInt(d);
		if (denominator <= 0)
			throw new NumberFormatException();
		minimize();
	}

/**
	Restituisce un Rational il cui valore e' (this + r)
	@param r valore da aggiungere a questo Rational.
	@return (this + r)

*/
public Rational add(Rational r)
	{
		int d = denominator * r.denominator;
		int n = (numerator * r.denominator) +
		        (denominator * r.numerator);
		return new Rational( Integer.toString(n),
				              Integer.toString(d));
	}

/**
	Restituisce un Rational il cui valore e' (this - r)
	@param r valore da sottrarre a questo Rational.
	@return (this - r)

*/
public Rational subtract(Rational r)
	{
		int d = denominator * r.denominator;
		int n = (numerator * r.denominator) -
				         (denominator * r.numerator);
		return new Rational(new Integer(n).toString(),
		                    new Integer(d).toString());
	}

/**
	Restituisce un Rational il cui valore e' (this * r)
	@param r valore da moltiplicare per questo Rational.
	@return (this * r)

*/
public Rational multiply(Rational r)
	{
		int d = denominator * r.denominator;
		int n = numerator * r.numerator;

		return new Rational( Integer.toString(d),
		                     Integer.toString(n));
	}

/**
	Restituisce un Rational il cui valore e' (this / r)
	@param r valore per cui deve essere diviso questo Rational.
	@return (this / r)
	@throws ArithmeticException - r==0

*/
public Rational divide(Rational r)
	{
		int d = denominator * r.numerator;
		int n = numerator * r.denominator;

		return new Rational( Integer.toString(n),
		                     Integer.toString(d));

	}

/**
	Restituisce la stringa decimale che rappresenta questo Rational ovvero
	il numeratore / il denominatore
	@return La stringa decimale che rappresenta questo Rational
*/
public String toString()
	{
		return numerator+"/"+denominator;
	}

/* selettori 
*/

public String getNumerator()
	{
		return Integer.toString(numerator);
	}
public String getDenominator()
	{
		return Integer.toString(denominator);
	}

/*
	Invariante di classe:
	- denominator > 0;
	- se questo Rational e' 0 allora numerator = 0 e denominator = 1
	  altrimenti MCD (numerator,denominator) = 1.
*/
private int numerator;
private int denominator;

/**
	Riporta questo numero razionale in forma canonica (riduce ai minimi termini)
*/
private void minimize()
	{
		if ( numerator == 0)
		{
			denominator = 1;
		}
		else
		{
			int m = MyMath.gcd(numerator, denominator);
			numerator = numerator / m;
			denominator = denominator / m;
		}
	}
}




