2012-04-09 07:35:18Morris
[JAVA][作業][Lab3] Rational.java
/** �* @author Shiang-Yun Yang �*/ public class Rational { private int numerator; private int denominator; private boolean simplify = false; /** �����* Initializes the class to 0/1. �����*/ public Rational() { this(0, 1); } /** �����* @param wholeNumber �����* Initializes the class to wholeNumber/1. �����*/ public Rational(int wholeNumber) { this(wholeNumber, 1); } /** �����* Initializes the class to theNum/theDen. �����* �����* @param theNum �����* assign this.numerator �����* @param theDen �����* assign this.denominator �����*/ public Rational(int theNum, int theDen) { numerator = theNum; denominator = theDen; simplify(); } /* �����* It's a copy constructor. It can't use �����* "this(val.numerator, val.denomiator)" after "if". Because �����* "Constructor call must be the first statement in a constructor" �����*/ public Rational(Rational val) { if (val == null) { System.out.println("Exception : Null Pointer."); System.exit(0); } numerator = val.numerator; denominator = val.denominator; simplify(); } /* �����* The following method will use "checkSimple()" to avoid "overflow". �����*/ /** �����* @return a Rational with val1 + val2 �����*/ public static Rational add(Rational val1, Rational val2) { checkSimple(val1); checkSimple(val2); int newNum, newDen; newDen = val1.denominator / gcd(val1.denominator, val2.denominator) * val2.denominator; newNum = val1.numerator * (newDen / val1.denominator) + val2.numerator * (newDen / val2.denominator); return new Rational(newNum, newDen); } /** �����* @return a Rational with val1 - val2 �����*/ public static Rational subtract(Rational val1, Rational val2) { checkSimple(val1); checkSimple(val2); int newNum, newDen; newDen = val1.denominator / gcd(val1.denominator, val2.denominator) * val2.denominator; newNum = val1.numerator * (newDen / val1.denominator) - val2.numerator * (newDen / val2.denominator); return new Rational(newNum, newDen); } /** �����* @return a Rational with val1 * val2 �����*/ public static Rational multiply(Rational val1, Rational val2) { checkSimple(val1); checkSimple(val2); int newNum, newDen; newNum = val1.numerator * val2.numerator; newDen = val1.denominator * val2.denominator; return new Rational(newNum, newDen); } /** �����* @return a Rational with val1 / val2 �����*/ public static Rational divide(Rational val1, Rational val2) { checkSimple(val1); checkSimple(val2); int newNum, newDen; newNum = val1.numerator * val2.denominator; newDen = val1.denominator * val2.numerator; return new Rational(newNum, newDen); } /** �����* Returns a Rational whose value is (this + val). �����* �����* @param val �����* value to be added to this Rational. �����* @return this + val �����*/ public Rational add(Rational val) { return Rational.add(this, val); } /** �����* Returns a Rational whose value is (this - val). �����* �����* @param val �����* value to be subtracted to this Rational. �����* @return this - val �����*/ public Rational subtract(Rational val) { return Rational.subtract(this, val); } /** �����* Returns a Rational whose value is (this * val). �����* �����* @param val �����* value to be multiplied by this Rational. �����* @return this * val �����*/ public Rational multiply(Rational val) { return Rational.multiply(this, val); } /** �����* Returns a Rational whose value is (this / val). �����* �����* @param val �����* value by which this Rational is to be divided. �����* @return this / val �����*/ public Rational divide(Rational val) { return Rational.divide(this, val); } /** �����* Returns a int whose value is the greatest common divisor of abs(x) and �����* abs(y). Returns 0 if x==0 && y==0. �����* �����* @return GCD(abs(x), abs(y)) �����*/ public static int gcd(int x, int y) { x = Math.abs(x); y = Math.abs(y); if (y == 0) return x; int tmp; while (x % y != 0) { tmp = x; x = y; y = tmp % y; } return y; } /** �����* Converts the rational number to simplified form. �����*/ private void simplify() { if (denominator == 0) { System.out.println("Exception : / by zero."); System.exit(0); } int GCD = gcd(numerator, denominator); numerator /= GCD; denominator /= GCD; if (denominator < 0) { numerator *= -1; denominator *= -1; } simplify = true; } public int getNumerator() { checkSimple(this); return this.numerator; } public int getDenominator() { checkSimple(this); return this.denominator; } /* �����* It can't use simplify() method after Mutator method because it will have �����* logic error. �����*/ public void set(int newNum, int newDen) { if (newDen == 0) { System.out.println("Exception : / by zero."); System.exit(0); } this.numerator = newNum; this.denominator = newDen; simplify = false; } public void set(Rational val) { this.set(val.numerator, val.denominator); } public void setNumerator(int newNum) { this.set(newNum, this.denominator); } public void setDenominator(int newDen) { this.set(this.numerator, newDen); } public String toString() { checkSimple(this); return numerator + "/" + denominator; } public double toDouble() { checkSimple(this); return (double) numerator / denominator; } public static void checkSimple(Rational val) { if (val.simplify == false) val.simplify(); } /* �����* I don't use public boolean equals(Rational x), because if you use Object �����* x = new Rational(5, 6); Rational y = new Rational(5, 6); then �����* x.equals(y), this way will get "false". Equals must be Reflexive, �����* Symmetric and Transitive. �����*/ @Override public boolean equals(Object x) { if (!(x instanceof Rational)) { return false; } checkSimple(this); checkSimple((Rational) x); return numerator == ((Rational) x).numerator && denominator == ((Rational) x).denominator; } }