import java.math.BigInteger; /** * This is a class for the performance of extended-precision rational * arithmetic. The objecs we create are immutable. */ public class BigFraction implements Comparable { /** * This is the BigFraction 1/1. */ public static final BigFraction ONE; /** * This is the BigFraction 0/1. */ public static final BigFraction ZERO; /** * This is the BigFraction 1/2. */ public static final BigFraction HALF; static { ONE = BigFraction.valueOf(1, 1); ZERO = BigFraction.valueOf(0, 1); HALF = BigFraction.valueOf(1, 2); } private final BigInteger num; private final BigInteger denom; /** * This constructor creates the BigFraction num/denom. * @param num the numerator of this BigFraction * @param denom the denominator of this BigFraction * @throws IllegalArgumentException if a zero is passed in as * a denominator */ public BigFraction(BigInteger num, BigInteger denom) { if(denom.compareTo(BigInteger.ZERO) < 0) { num = num.negate(); denom = denom.negate(); } BigInteger d = num.gcd(denom); this.num = num.divide(d); this.denom = denom.divide(d); } /** * This constructor creates the BigFraction num/denom. The fraction will be * represented in its fully reduced form with any negative in the numerator. * @param num a numerical String representing the numerator of this BigFraction * @param denom a numerical String representing the denominator of this BigFraction */ public BigFraction(String num, String denom) { this(new BigInteger(num), new BigInteger(denom)); } /** * This static factory method creates a BigFraction from two longs. * @param num the numerator of this BigFraction * @param denom the denominator of this BigFraction * @return a new BigFraction representing num/denom. */ public static BigFraction valueOf(long num, long denom) { return new BigFraction(BigInteger.valueOf(num), BigInteger.valueOf(denom)); } /** * This makes a string representation of the form num/denom. * @return a string of the form num/denom. */ public String toString() { return String.format("%s/%s", num, denom); } /** * This tests fractions for numerical equality. * @param o the object we are checking for equality with this BigFraction * @return true if o is a BigFraction and if it is numerically equal to * this BigFraction. */ public boolean equals(Object o) { if( !(o instanceof BigFraction)) { return false; } BigFraction that = (BigFraction) o; return num.equals(that.num) && denom.equals(that.denom); } /** * This computes this + that. * @param that is a BigFraction we are adding to this BigFraction * @return this + that */ public BigFraction add(BigFraction that) { // a/b + c/d = (ad + bc)/bd; BigInteger top = num.multiply(that.denom).add(denom.multiply(that.num)); BigInteger bottom = denom.multiply(that.denom); return new BigFraction(top, bottom); } /** * This computes this - that. * @param that is a BigFraction we are adding to this BigFraction * @return this - that */ public BigFraction subtract(BigFraction that) { // a/b - c/d = (ad - bc)/bd; BigInteger top = num.multiply(that.denom).subtract(denom.multiply(that.num)); BigInteger bottom = denom.multiply(that.denom); return new BigFraction(top, bottom); } /** * This computes this * that. * @param that is a BigFraction we are adding to this BigFraction * @return this * that */ public BigFraction multiply(BigFraction that) { // a/b * c/d = (ac)/bd; BigInteger top = num.multiply(that.num); BigInteger bottom = denom.multiply(that.denom); return new BigFraction(top, bottom); } /** * This computes this / that. * @param that is a BigFraction we are adding to this BigFraction * @return this / that */ public BigFraction divide(BigFraction that) { // (a/b) / (c/d) = (ad)/bc; BigInteger top = num.multiply(that.denom); BigInteger bottom = denom.multiply(that.num); return new BigFraction(top, bottom); } /*Programming Exercises *******************/ /** * This computes thisn. * @param n the power we are raising this BigInteger to. * @return thisn */ public BigFraction pow(int n) { return null; } /** * This computes the integer part of this BigFraction, truncating toward zero. * @return a BigInteger representing the integer part of this BigFraction. */ public BigInteger bigIntegerValue() { return null; } /** * This returns a new BigFraction represeting -this. * @return -this */ public BigFraction negate() { return null; } /** * This computes the absolute value of a BigFraction as a BigFraction. * @return |this| */ public BigFraction abs() { return null; } /** * This method retursn a negative integer if this < that, a positive integer * if this > that, and zero if this equals that. * @param that the BigFraction we are comparing this BigFraction to * @return a negative integer if this < that, a positive integer * if this > that and zero if this equals that. */ public int compareTo(BigFraction that) { return 0; } //return max(this, that) public BigFraction max(BigFraction that) { return null; } //return min(this, that) public BigFraction min(BigFraction that) { return null; } public static BigFraction harmonic(int n) { //return the nth harmonic number return null; } //annoying challenge problem. //return this big fraction as a double. Sticky question: //how to deal with the infinite and zero cases..... //Note static members Double.NEGATIVE_INFINITY and Double.INFINITY. //test carefully. It's quite hard to get this right. public double doubleValue() { return 0; } public static void main(String[] args) { BigFraction f = BigFraction.valueOf(2,3); BigFraction g = BigFraction.valueOf(2, 4); BigFraction gag = BigFraction.valueOf(1,2); System.out.println(f.add(gag).equals(BigFraction.valueOf(7,6))); System.out.println(f.subtract(gag).equals(BigFraction.valueOf(1,6))); System.out.println(f.multiply(g).equals(BigFraction.valueOf(1,3))); System.out.println(f.divide(g).equals(BigFraction.valueOf(4,3))); System.out.printf("%s equals %s: %s\n", g, gag, g.equals(gag)); BigFraction h = BigFraction.valueOf(7776, 1048576); System.out.println(f); System.out.println(g); System.out.println(h); System.out.println(f.add(g)); BigFraction total = BigFraction.ZERO; BigFraction x = new BigFraction("1331", "726"); System.out.println(x); for(int k = 1; k <= 100; k++) { total = total.add(BigFraction.valueOf(1,k)); } System.out.println(total); } }