/** * A simple (and partial) implementation of fractions. * * @author Samuel A. Rebelsky * @author Clif Flynt * @version 1.1 of February 1999 */ public class Fraction { // +--------+-------------------------------------------------- // | Fields | // +--------+ /** The numerator. */ protected long num; /** The denominator. */ protected long denom; // +--------------+-------------------------------------------- // | Constructors | // +--------------+ /** * Create the fraction a/b (simplifying if necessary). */ public Fraction(long a, long b) { this.num = a; this.denom = b; this.simplify(); } // Fraction(long,long) /** * Create the ``zero'' fraction (0/1 for convenience). */ public Fraction() { this.num = 0; this.denom = 1; } // Fraction() /** * Create a ``whole'' fraction (the fraction corresponding * to an integer). */ public Fraction(long val) { this.num = val; this.denom = 1; } // Fraction(long) // +------------------+---------------------------------------- // | Standard Methods | // +------------------+ /** * Determine if this fraction equals another fraction. */ public boolean equals(Fraction other) { // A denominator of 0 is problematical. If both are 0, we'll // assume that they're equal. if ((this.denom == 0) && (other.denom == 0)) { return true; } // If only one denominator is 0, we'll assume they're different. else if ((this.denom == 0) || (other.denom == 0)) { return false; } // a/b = c/d if a*d=b*c. (There's some disadvantage to this // technique because a*c or b*d can overflow.) else { return (this.num*other.denom) == (other.num*this.denom); } } // equals(Fraction) /** * Determine if this fraction equals another object. */ public boolean equals(Object other) { System.out.println("Object method called" + other); return (other instanceof Fraction) && (equals((Fraction) other)); } // equals(Object) /** * Convert this fraction to a string. */ public String toString() { // Special case: denominator is 0. Return an error string. if (this.denom == 0) { return "Not a number"; } // Special case: denominator is 1. Return just the numerator. else if (this.denom == 1) { return Long.toString(this.num); } // Normal case. Return the fraction in the form a/b. else { return (this.num + "/" + this.denom); } } // toString() // +--------------------+-------------------------------------- // | Additional Methods | // +--------------------+ /** * Compute the fraction that results from adding this fraction * to another fraction. * * a/b + c/d = (a*d + b*c)/(b*d) */ public Fraction add(Fraction other) { return new Fraction( this.num*other.denom + other.num*this.denom, this.denom*other.denom); } // add(Fraction) /** * Compute the fraction that results from dividing this * fraction by another faction. * * (a/b)/(c/d) = a/b * d/c = (a*d)/(b*c) */ public Fraction divide(Fraction other) { return new Fraction( this.num*other.denom, this.denom*other.num); } // divide(Fraction) /** * Compute the fraction that results from multiplying this * fraction by another faction. * * a/b * c/d = (a*d)/(b*d) */ public Fraction multiply(Fraction other) { return new Fraction( this.num*other.num, this.denom*other.denom); } // multiply(Fraction) /** * Compute the fraction that results from subtracting another * fraction from this faction. * * a/b - c/d = (a*d - b*c)/(b*d) */ public Fraction subtract(Fraction other) { return new Fraction( this.num*other.denom - other.num*this.denom, this.denom*other.denom); } // subtract(Fraction) // +---------------------------+------------------------------- // | Computation with integers | // +---------------------------+ public Fraction add(long other) { return this.add(new Fraction(other)); } // add(long) public Fraction subtract(long other) { return this.subtract(new Fraction(other)); } // subtract(long) public Fraction multiply(long other) { return this.multiply(new Fraction(other)); } // multiply(long) public Fraction divide(long other) { return this.divide(new Fraction(other)); } // divide(long) // +----------------+------------------------------------------ // | Helper Methods | // +----------------+ /** * Compute the greatest common divisor of nonnegative integers * a and b. May be useful in simplifying a fraction. Uses a * legendary algorithm. */ protected long gcd(long a, long b) { // Special case, required by the algorithm. If b is 0, then // return a. if (b == 0) { return a; } // Other case. else { return gcd(b, a%b); } } // gcd(long,long) /** * Simplify the current fraction. */ protected void simplify() { // Divide numerator and denominator by their GCD. The GCD // algorithm only works with nonneative integers, so we must // take the absolute value of both parameters. long div = gcd(Math.abs(this.num), Math.abs(this.denom)); this.num = this.num/div; this.denom = this.denom/div; // Now we can deal with negative denominators. The tradition // is that denominators are always positive. Hence, we multiply // both parts by -1. Note that this also repairs the problem of // things like -2/-3 (which should be 2/3). if (this.denom < 0) { this.num = this.num * -1; this.denom = this.denom * -1; } // if the denominator is negative } // simplify() } // class Fraction