import java.math.BigInteger; import java.util.ArrayList; import java.util.Collections; //we agree to have a compareTo method //public int compareTo(BigFraction that) //compiler enforces contract. /** * This is a a class of immutible extended-precision rational * numbers. All BigFractions are fully reduced and any * negative is in the numerator. */ public class BigFraction implements Comparable { //static matter /** This is the BigFraction 1/1. */ public static BigFraction ONE; /** This is the BigFraction 0/1. */ public static BigFraction ZERO; /** This is the BigFraction 1/2. */ public static BigFraction HALF; //static block initalizes static data. static { ONE = BigFraction.valueOf(1,1); HALF = BigFraction.valueOf(1,2); ZERO = new BigFraction(); } private final BigInteger num; private final BigInteger denom; /** * This is a general-purpose constructor that * creates a BigFraction from a specified numerator * denominator. * @param num the numerator of this BigFraction * @param denom the denominator of this BigFraction * @throws IllegalArgumentException if a zero denominator * is provided. */ public BigFraction(BigInteger num, BigInteger denom) { if(denom.equals(BigInteger.ZERO)) { throw new IllegalArgumentException(); } if(denom.compareTo(BigInteger.ZERO) < 0) { num = num.negate(); denom = denom.negate(); } BigInteger d = num.gcd(denom); num = num.divide(d); denom = denom.divide(d); this.num = num; this.denom = denom; } /** * This creates the BigFraction num/1. * @param num the numerator of this BigFraction. The denominator * will be 1. */ public BigFraction(BigInteger num) { this(num, BigInteger.ONE); } /** * This no-args constructor creates the BigFraction 0/1. */ public BigFraction() { this(BigInteger.ZERO, BigInteger.ONE); } /** * This static factory method produces a BigFraction * with specified numerator and denominator that are longs. * @param num the numerator * @param denom the denominator * @return the BigFraction num/denom */ public static BigFraction valueOf(long num, long denom) { return new BigFraction(BigInteger.valueOf(num), BigInteger.valueOf(denom)); } /** * This gives a string representation of the form num/denom. * @return A string of the form num/denom representing this * BigFraction. */ @Override public String toString() { return String.format("%s/%s", num, denom); } /** * This returns true when o is a BigFraction numerically * equal to this BigFraction. * @param o an object we are comparing this BigFraction to. * @return true if o is a BigFraction numerically equal to * this BigFraction. */ @Override public boolean equals(Object o) { if(this == o) return true; if( !(o instanceof BigFraction)) { return false; } BigFraction that = (BigFraction) o; return num.equals(that.num) && denom.equals(that.denom); } /** * This compares this BigFraction to the BigFraction that. * @param that the BigFraction we are comparing this BigFraction * to. * @return a negative integer if this < that and a positive * integer if this > that, and zero otherwise. */ @Override public int compareTo(BigFraction that) { BigInteger cross = num.multiply(that.denom) .subtract(denom.multiply(that.num)); return cross.compareTo(BigInteger.ZERO); } /** * This computes the sum of two BigFractions. * @param that the BigFraction we are adding this BigFraction * to. * @return this + that as a BigFraction. */ public BigFraction add(BigFraction that) { BigInteger top = num.multiply(that.denom) .add(denom.multiply(that.num)); BigInteger bottom = denom.multiply(that.denom); return new BigFraction(top, bottom); } /** * This computes the difference of two BigFractions. * @param that the BigFraction we are subtraction from * this BigFraction. * @return this - that as a BigFraction. */ public BigFraction subtract(BigFraction that) { BigInteger top = num.multiply(that.denom) .subtract(denom.multiply(that.num)); BigInteger bottom = denom.multiply(that.denom); return new BigFraction(top, bottom); } /** * This computes the product of two BigFractions. * @param that the BigFraction we are multiplying by. * this BigFraction. * @return this*that as a BigFraction. */ public BigFraction multiply(BigFraction that) { BigInteger top = num.multiply(that.num); BigInteger bottom = denom.multiply(that.denom); return new BigFraction(top, bottom); } /** * This computes the quotient of two BigFractions. * @param that the BigFraction we are dividing by. * this BigFraction. * @return this/that as a BigFraction. */ public BigFraction divide(BigFraction that) { BigInteger top = num.multiply(that.denom); BigInteger bottom = denom.multiply(that.num); return new BigFraction(top, bottom); } /** * This computes thisn. * @param n the power we are raising this BigFraction to. * @return thisn */ public BigFraction pow(int n) { BigInteger top = num.pow(n); BigInteger bottom = denom.pow(n); if(n >= 0) { return new BigFraction(top, bottom); } if(n < 0) { n = -n; return new BigFraction(bottom, top); } } /** * Test code goes in here * @param args command-line arguments */ public static void main(String[] args) { BigFraction f = BigFraction.valueOf(2,4); System.out.println(f); BigFraction g = BigFraction.valueOf(-2, -4); System.out.println(g); BigFraction a = BigFraction.valueOf(1,2); BigFraction b = BigFraction.valueOf(1,3); System.out.println(a.add(b)); BigFraction out = BigFraction.valueOf(1,1); for(int k = 2; k <= 1000; k++) { out = out.add(BigFraction.valueOf(1,k)); } System.out.println(out); //BigFraction is a legit type! ArrayList al = new ArrayList<>(); al.add(BigFraction.valueOf(1,4)); al.add(BigFraction.valueOf(1,3)); al.add(BigFraction.valueOf(1,5)); al.add(BigFraction.valueOf(1,7)); al.add(BigFraction.valueOf(1,6)); al.add(BigFraction.valueOf(1,8)); System.out.println(al); //Bonus: implementing Comparable gives us this //wonderful service. Our BigFractions are sortable! Collections.sort(al); System.out.println(al); } }