M. Warren
M. Warren

Reputation: 29

Java fraction calculator reduce method

I am doing a java fraction calculator for my AP computer science class and I am having problems with my reduce method. I think it's just returning the first fraction entered as the reduced answer. For example, 4/5 * 5/4 returns 20/20 without reduce method call. This answer is correct but when I apply my reduce method it returns 4/5 (the first fraction) instead of 1(or 1/1) Any feedback is always helpful. Here is my code:

// begin fraction class.
public class Fraction {
    // instance variables for the first fractions numerator and denominator.
    private  int numerator;
    private  int denominator;


    public Fraction(String fraction) {

        // This if statement checks for mixed numbers (indicated by the underscore)
        if (fraction.contains("_")) {
            // gets from 0 to before the first underscore is present to find the value of the whole number in the string.
            int wholeNumber1 = Integer.parseInt(fraction.substring(0, fraction.indexOf("_")));

            // does the same for numerator.
            numerator = Integer.parseInt(fraction.substring(fraction.indexOf("_") + 1, fraction.indexOf("/")));

            // does the same for denominator.
            denominator = Integer.parseInt(fraction.substring(fraction.indexOf("/") + 1));

            // sets mixed numbers into improper fractions
            numerator = (wholeNumber1 * denominator) + numerator;


        } else if (fraction.contains("/")) {
            // this if statement checks for regular fractions.

            // locates the numerator in the string.
            numerator = Integer.parseInt(fraction.substring(0, fraction.indexOf("/")));

            //locates the denominator in the string
            denominator = Integer.parseInt(fraction.substring(fraction.indexOf("/") + 1));

        } else {
            // this else statement assumes that the user enters a whole number.

            int wholeNumber2 = Integer.parseInt(fraction.substring(0));
            numerator = wholeNumber2;
            // puts the whole number over 1 to make an improper fraction. This will probably be reduced in another method.
            denominator = 1;

        }

    } // end of Fraction constructor


    // Starting methods for checkpoint 4+

    public Fraction (int numerator, int denominator) {

        // we used this.numerator and this.denominator to make it clear which variable is being referred to.
        this.numerator = numerator;
        this.denominator = denominator;

    } // end of second Fraction constructor.

    // method for formatting fractions.
    public  String toString() {
        return String.valueOf(numerator) + "/" + String.valueOf(denominator);
    }

    // multiply method.
    public Fraction multiply(Fraction secondFraction) {

        int productOfNumerators = numerator * secondFraction.numerator;
        int productOfDenominators = denominator * secondFraction.denominator;

        // object to call the second constructor.
        Fraction product = new Fraction(productOfNumerators, productOfDenominators);
        return product;

    } // end multiply method

    // divide method.
    public Fraction divide(Fraction secondFraction) {

        // product of numerators and denominators for cross multiplication.
        int productOfNumerators = numerator * secondFraction.denominator;
        int productOfDenominators = denominator * secondFraction.numerator;

        // object to call the second constructor.
        Fraction quotient = new Fraction(productOfNumerators, productOfDenominators);

        return quotient;
    } // end divide method

    // add method.
    public Fraction add(Fraction secondFraction) {

        if(denominator != secondFraction.denominator) {

            int sumOfDenominators = denominator * secondFraction.denominator;
            int newNumeratorOne = numerator * secondFraction.denominator;
            int newNumeratorTwo = secondFraction.numerator * denominator;
            int sumOfNumerators = newNumeratorOne + newNumeratorTwo;

            Fraction sum = new Fraction(sumOfNumerators, sumOfDenominators);
            return sum;
        } else {

            int sumOfNumerators = numerator + secondFraction.numerator;
            Fraction sum = new Fraction(sumOfNumerators, denominator);
            return sum;
        }

    } // end add method.

    // subtract method.
    public Fraction subtract(Fraction secondFraction) {

        if(denominator != secondFraction.denominator) {

            int differenceOfDenominators = denominator * secondFraction.denominator;
            int newNumeratorOne = numerator * secondFraction.denominator;
            int newNumeratorTwo = secondFraction.numerator * denominator;
            int differenceOfNumerators = newNumeratorOne - newNumeratorTwo;

            Fraction difference = new Fraction(differenceOfNumerators, differenceOfDenominators);
            return difference;
        } else {

            int sumOfNumerators = numerator - secondFraction.numerator;
            Fraction difference = new Fraction(sumOfNumerators, denominator);
            return difference;
        }

    } // end subtract method.

    // reduce method.
    public Fraction reduce (Fraction secondFraction) {
        int numerator_abs = Math.abs (numerator);
        int denominator_abs = Math.abs (denominator);

        int min_num = Math.min(numerator_abs, denominator_abs);

        Fraction reducedAnswer = new Fraction(numerator_abs, denominator_abs);

        for (int i = 1; i <= min_num; i++) {
            if (numerator%i == 0 && denominator%i == 0){
                i++;
            }//end if
        }//end for
        return reducedAnswer;

    }//end reduce



} // end class

Upvotes: 2

Views: 3452

Answers (3)

Frelling
Frelling

Reputation: 3507

Your reduce method simply sets the result before your reduced loop, which itself appears to have no effect. Given that reduction is a purely a fraction characteristic, it should be a method of your fraction class. Also Elucid’s GCD more effective for calculating the greatest common denominator. Given that, I suggest the following.

public class Fraction {
    ...

    public void reduce() {
        int gcd = getGcd( numerator, denominator );
        if ( gcd == 1 )
            return;
        else {
            numerator /= gcd;
            denominator /= gcd;
        }
    }

    private int getGcd( int a, int b ) {
        if ( b == 0 )
            return a;
        else
            return getGcd( a, a%b );
    }
}

Upvotes: 0

kulturman
kulturman

Reputation: 13

You can write your reduce method like this

public void reduce ()
{
    BigInteger num = BigInteger.valueOf(numerator);
    int gcd = num.gcd(BigInteger.valueOf(denominator)).intValue();

    this.denominator /= gcd;
    this.numerator /= gcd;

}

Upvotes: 0

elyashiv
elyashiv

Reputation: 3691

In the reduce function you don't change reducedAnswer, so you don't realy reduce the fraction.

Also, you are returning the abs value of the fraction, witch is probably not what you want.

BTW - you might want to use https://en.wikipedia.org/wiki/Euclidean_algorithm for finding the greatest common divisor in the reduction proccess.

Upvotes: 2

Related Questions