Academic Integrity: tutoring, explanations, and feedback — we don’t complete graded work or submit on a student’s behalf.

Problem For this programming assignment, you are to complete the Fraction class

ID: 667929 • Letter: P

Question

Problem

For this programming assignment, you are to complete the Fraction class discussed in class and the provided partial test driver (both given below) for testing your class.

Modifications to Make

Modify setters so that they ignore inappropriate values (i.e., divide by zero)

Implement the equals() method inherited from the top-level Object class

Implement less than and greater than methods

Implement add, subtract, and multiply methods

Complete the test driver for your Fraction class to test the newly-added methods.

FRACTION CLASS

public class Fraction {                                                                                      

         private int numer;

         private int denom;

   

         public Fraction() { // no-arg constructor

                  numer = 0;

        denom = 1;

         }

   

         public Fraction(int numer, int denom) {

        this.numer = numer;

        this.denom = denom;

         }

   

         public Fraction(Fraction frac) { // copy constructor

        numer = frac.getNumer();

        denom = frac.getDenom();

         }

         // getters and setters

         public int getNumer() {

        return numer;

         }

   

         public void setNumer(int x) {

        numer = x;

         }

   

         public int getDenom() {

        return denom;

         }

   

         public void setDenom(int x) {

        denom = x;

         }

  

         // Special Methods

         public String toString() {

        return numer + "/" + denom;

         }

         // Other Methods

         public Fraction reduce() {

        Fraction temp = new Fraction();

       

        int GCD = gcd(numer, denom);

       

        temp.setNumer(numer / GCD);

        temp.setDenom(denom / GCD);

       

        return temp;

         }

        

         // Private Methods

         private int gcd(int n1, int n2)

         {

        int M, N, R;

       

        if (n1 < n2)

        {

                           N = n1;

                           M = n2;

        }

        else

        {

                           N = n2;

                           M = n1;

        }

       

        R = M % N;

       

        while (R != 0)

        {

                           M = N;

                           N = R;

           

                           R = M % N;

        }

       

        return N;

       

        }

}

FRACTION CLASS TEST DRIVER

public class FractionClassTestDriver {                                                            

         public static void main(String[] args) {

        

        // test constructors

        Fraction frac0 = new Fraction();

        System.out.println("TESTING NO-ARG CONSTRUCTOR");

                  System.out.println(“frac0: Result should be 0/1:”);

        System.out.println("Numer = " + frac0.getNumer());

        System.out.println("Denom = " + frac0.getDenom());

        

        System.out.println("TESTING int/int CONSTRUCTOR");

        Fraction frac1 = new Fraction(2,4);

                  System.out.println(“frac1: Result should be 2/4:”);

        System.out.println("Numer = " + frac1.getNumer());

        System.out.println("Denom = " + frac1.getDenom());

      

        System.out.println("TESTING Fraction CONSTRUCTOR");

        Fraction frac2 = new Fraction(frac1);

                  System.out.println(“frac2: Result should be 2/4:”);

        System.out.println("Numer = " + frac2.getNumer());

        System.out.println("Denom = " + frac2.getDenom());

                  System.out.println("TESTING COPY CONSTRUCTOR frac1 à frac2");

        if (frac1.getNumer() == frac2.getNumer() &&

                           frac1.getDenom() == frac2.getDenom() &&

                           frac1 != frac2)

        {

                           System.out.println("Copy constructor working");

        }

        else

                           System.out.println("PROBLEM with copy constructor");

      

        // test equal method

        System.out.println("TESTING EQUALITY OF frac1 and frac2 -");

                  System.out.println("SHOULD BE FOUND EQUAL:");

                  if (frac1.equals(frac2))

        {

                           System.out.println("frac1 and frac2 found equal");

        }

        else

        {

                           System.out.println("frac1 and frac2 NOT equal");

        }

                  // test reduce method

        System.out.println("TESTING reduce METHOD ON frac1");

                  Fraction reduced_frac1 = frac1.reduce();

        System.out.println("Reduced frac1 = " + reduced_frac1);

       

        // test getters and setters

        frac2.setNumer(8);

        frac2.setDenom(12);

         System.out.println("Numer = " + frac2.getNumer());

        System.out.println("Denom = " + frac2.getDenom());

       

        // System.out.println("GCD of 2/4 = " + frac1.gcd(1,4));

      

         }

         * TO BE COMPLETED *

}

Explanation / Answer

Fraction.java


import java.math.BigInteger;

public class Fraction {

    private int m_numerator;
    private int m_denominator;
  
    public static final Fraction ZERO_FRACTION = new

Fraction(0, 1);
  
    public Fraction(int numerator, int denominator) throws

ArithmeticException {
        setNumerator(numerator);
        setDenominator(denominator);
    }

    public int getNumerator() {
        return m_numerator;
    }

    private void setNumerator(int numerator) {
        this.m_numerator = numerator;
    }

    public int getDenominator() {
        return m_denominator;
    }

    private void setDenominator(int denominator) {
        if(0 == denominator) {
            throw new ArithmeticException

("Fraction with a Zero denominator encountered !!!");
        }
        this.m_denominator = denominator;
    }

    public Fraction add(Fraction f) {
        return additionSubtractionUtil(f, true);
    }
  
    public Fraction subtract(Fraction f) {
        return additionSubtractionUtil(f, false);
    }
  
    public Fraction multiply(Fraction f) {

        if (f == null) {
            throw new IllegalArgumentException("Multiplying

with a null is not permitted !!!");
        }
        if(this.getNumerator() == 0 || f.getNumerator() == 0)

{
            return ZERO_FRACTION;
        }

        // this is to make sure that the values will not

overflow unless they are supposed to
        int gcd1 = getGCD(this.getNumerator(),

f.getDenominator());
        int gcd2 = getGCD(f.getNumerator(),

this.getDenominator());
      
        return getReducedFraction
            (multiplyAndCheckOverflow(this.getNumerator

()/gcd1, f.getNumerator()/gcd2),
             multiplyAndCheckOverflow(this.getDenominator

()/gcd2, f.getDenominator()/gcd1));
    }
  
    private Fraction getReducedFraction(int numerator, int

denominator) {
      
        if (denominator == 0) {
            throw new ArithmeticException("Fraction cannot

have a Zero denominator !!!");
        }
        if (numerator==0) {
            return ZERO_FRACTION;
        }
      
        int gcd = getGCD(numerator, denominator);
        numerator /= gcd;
        denominator /= gcd;
        return new Fraction(numerator, denominator);
    }
  
    public Fraction divide(Fraction f) {
      
        if (f == null) {
            throw new IllegalArgumentException("Division by a

Null Fraction is not permitted !!!");
        }
        if (f.getNumerator() == 0) {
            throw new ArithmeticException("Divide By Zero

Fraction Exception !!!");
        }
      
        return multiply(f.invert());
    }
  
    public boolean equals(Fraction f) {
      
        if(f instanceof Fraction) {
            return compareTo(f) == 0 ? true :

false;
        }
      
        return false;
      
    }
  
    public boolean greaterThan(Fraction f) {
      
        if(f == null) {
            throw new IllegalArgumentException

("Greater than comparison cannot be done on a Null Fraction

!!!");
        }
      
        return compareTo(f) == 1 ? true : false;
    }
  
    public void display() {
        System.out.println(this.getNumerator() + "/" +

this.getDenominator());
    }
  
    public boolean lessThan(Fraction f) {
      
        if(f == null) {
            throw new IllegalArgumentException

("Less Than comparison cannot be done on a Null Fraction

!!!");
        }
      
        return compareTo(f) == -1 ? true : false;
    }

    private Fraction invert() {
      
        if (this.getNumerator() == 0) {
            throw new ArithmeticException("Cannot invert a

Zero Fraction !!!");
        }
        if (this.getNumerator() == Integer.MIN_VALUE) {
            throw new ArithmeticException("Inversion of

Integer.MIN_VALUE lead to Overflow error !!!");
        }
      
        if (this.getNumerator() < 0) {
            return new Fraction(-this.getDenominator(), -

this.getNumerator());
        } else {
            return new Fraction(this.getDenominator(),

this.getNumerator());
        }
    }

    private int compareTo(Fraction f) {
      
        if (this == f) {
            return 0;
        }
        if (this.getNumerator() == f.getNumerator() &&
                this.getDenominator() ==

f.getDenominator()) {
            return 0;
        }

        long v1 = (long) this.getNumerator() * (long)

f.getDenominator();
        long v2 = (long) f.getNumerator() * (long)

this.getDenominator();
      
        if (v1 == v2) {
            return 0;
        } else if (v1 < v2) {
            return -1;
        } else {
            return 1;
        }
    }
  
    private Fraction negate() {
      
        if (this.getNumerator() == Integer.MIN_VALUE)

{
            throw new ArithmeticException("Integer Minimum

Negation Overflow !!!");
        }
      
        return new Fraction(-this.getNumerator(),

this.getDenominator());
    }

    private Fraction additionSubtractionUtil(Fraction f,

boolean isAddition) {
      
        if (null == f) {
            throw new IllegalArgumentException("Cannot

add/subtract a Fraction !!!");
        }
        if (0 == f.getNumerator()) {
            return this;
        }       
        if (this.getNumerator() == 0) {
            return isAddition ? f : f.negate();
        }
          
        int gcd1 = getGCD(this.getDenominator(),

f.getDenominator());
        if (1 == gcd1) {
            // If no possible gcd, we just multiply and

throw an exception in case of overflow
            int v1 = multiplyAndCheckOverflow

(this.getNumerator(), f.getDenominator());
            int v2 = multiplyAndCheckOverflow(f.getNumerator

(), this.getDenominator());
            return new Fraction(
                        isAddition ?

addAndCheckOverflow(v1, v2) : subtractAndCheckOverflow(v1,

v2),
                              

multiplyAndCheckOverflow(this.getDenominator(),

f.getDenominator())
                    );
        }

        // Keep this in mind to follow the next sequence of

actions
        // (a/b)+(c/d) = (a*d+b*c)/(b*d) = [((a*d

+b*c)/gcd1)/gcd2]/[b*d/gcd1*gcd2]
      
        // normalizing the value in numerator using gcd1
        BigInteger v1 = BigInteger.valueOf(this.getNumerator

()).multiply(BigInteger.valueOf(f.getDenominator()/gcd1));
        BigInteger v2 = BigInteger.valueOf(f.getNumerator

()).multiply(BigInteger.valueOf(this.getDenominator()/gcd1));
        BigInteger num1 = isAddition ? v1.add(v2) :

v1.subtract(v2);
      
        // further normalizing the numerator using next

possible gcd
        int num1Mod = num1.mod(BigInteger.valueOf

(gcd1)).intValue();
        int gcd2 = (num1Mod==0) ? gcd1 : getGCD(num1Mod,

gcd1);

        // result is equal to (num1/gcd2) /

(first.denominator/gcd1)(second.denominator/gcd2)
        BigInteger res = num1.divide(BigInteger.valueOf

(gcd2));
        if (res.bitLength() > 31) {
            throw new ArithmeticException("Multiplication

Overflow error !!!");
        }
      
        return new Fraction(res.intValue(),

multiplyAndCheckOverflow(
                this.getDenominator() / gcd1,

f.getDenominator() / gcd2));
      
    }

    private int subtractAndCheckOverflow(int v1, int v2) {
      
        long sub = ((long)v1)-((long)v2);
        if (sub < Integer.MIN_VALUE ||
            sub > Integer.MAX_VALUE) {
            throw new ArithmeticException("Integer Subtraction

Overflow !!!");
        }
      
        return (int)sub;
    }

    private int addAndCheckOverflow(int v1, int v2) {
      
        long add = ((long)v1)+((long)v2);
        if (add < Integer.MIN_VALUE ||
            add > Integer.MAX_VALUE) {
            throw new ArithmeticException("Integer Addition

Overflow !!!");
        }
     
        return (int)add;
    }

    private int multiplyAndCheckOverflow(int v1, int v2)

throws ArithmeticException {
      
        long mul = ((long)v1)*((long)v2);
        if(mul < Integer.MIN_VALUE || mul >

Integer.MAX_VALUE) {
            throw new ArithmeticException("Integer

Multiplication Overflow for { " + v1 + " } { " + v2 + " }");
        }
      
        return (int)mul;
    }

    private int getGCD(int v1, int v2) {

        BigInteger a = new BigInteger(new

StringBuffer().append(v1).toString());
        BigInteger b = new BigInteger(new

StringBuffer().append(v2).toString());
        BigInteger c = a.gcd(b);
      
        if (c.bitLength() > 31) {
            throw new ArithmeticException("Overflow during GCD

computation !!!");
        }
        return c.intValue();
      
    }
  
}

Hire Me For All Your Tutoring Needs
Integrity-first tutoring: clear explanations, guidance, and feedback.
Drop an Email at
drjack9650@gmail.com
Chat Now And Get Quote