Проблемы с делением на отрицательные дроби

Я работаю над заданием по кодированию, где я должен написать методы для упрощения, поиска gcf, сложения, вычитания, умножения и деления двух дробей. Я написал все методы, но у меня возникли проблемы с методом деления, потому что всякий раз, когда я пытаюсь разделить на отрицательную дробь (например, -6/17), в результате печатается 0/1. Вот мой класс Fraction со всеми методами, но я добавил только перечисленные выше. Остальное дал мой инструктор. Вот класс:

class Fraction {
    private int numerator = 0; // numerator (and keeps sign)
    private int denominator = 1; // always stores positive value

    public Fraction() {
    }

    public Fraction(int n, int d) {
        if (set(n, d) == false)
           set(0, 1);
    }

    public boolean set(int n, int d) {
        if (d > 0) {
           numerator = n;
           denominator = d;
           return true;
        } else
           return false;
    }

    public String toString() {
       return (numerator + "/" + denominator);
    }

    public int getNumerator() {
        return numerator;
    }

    public int getDenominator() {
        return denominator;
    }

    public double decimal() {
        return (double) numerator / denominator;
    }

    public Fraction simplify(){
       int gcd = GetGcd(this);

       int simpNum = this.numerator;
       int simpDen = this.denominator;

       simpNum /= gcd;
       simpDen /= gcd;

       Fraction f = new Fraction (simpNum, simpDen);
       return f;
    }

    public int GetGcd (Fraction f){
       int testNum = f.numerator;
       int testDen = f.denominator;

       if (testNum < 0)
           testNum = 0 - testNum;
       else if (testDen < 0)
           testDen = 0 - testDen;

       if (testNum == 0){
           return testDen;
       }

       while (testNum != testDen){
           if (testNum > testDen)
              testNum -= testDen;
           else
              testDen -= testNum;

       }
      return testNum;
    }

    public Fraction add (Fraction f){
       int cd = this.denominator * f.denominator;

       int den1 = this.denominator;
       int den2 = f.denominator;
       int num1 = this.numerator * (cd / den1);
       int num2 = f.numerator * (cd / den2);
       int num3 = num1 + num2;
       Fraction f2 = new Fraction (num3, cd);
       f2 = f2.simplify();
       return f2;
    }

    public Fraction subtract (Fraction f){
       int cd = this.denominator * f.denominator;

       int den1 = this.denominator;
       int den2 = f.denominator;
       int num1 = this.numerator * (cd / den1);
       int num2 = f.numerator * (cd / den2);
       int num3 = num1 - num2;

       Fraction f2 = new Fraction (num3, cd);
       f2 = f2.simplify();
       return f2;
    }

    public Fraction multiply (Fraction f){
       int den1 = this.denominator;
       int den2 = f.denominator;
       int num1 = this.numerator;
       int num2 = f.numerator;
       int num3 = num1 * num2;
       int den3 = den1 * den2;

       Fraction f2 = new Fraction (num3, den3);
       f2 = f2.simplify();
       return f2;
    }

    public Fraction divide (Fraction f){
       int den1 = this.denominator;
       int den2 = f.denominator;
       int num1 = this.numerator;
       int num2 = f.numerator;

       int num3 = num1 * den2;
       int den3 = den1 * num2;

       Fraction f2 = new Fraction (num3, den3);
       f2 = f2.simplify();
       return f2;
    }
}

И мой инструктор дал мне тестовый код с тестовыми дробями. Вот:

    public class FractionTester {
    public static void main (String[] args) {

    System.out.println("\n\nFraction tests:\n");

    Fraction f1 = new Fraction(4, 6);
    Fraction f2 = new Fraction(75, 175);
    Fraction f3 = new Fraction(-6, 17);

    System.out.println(f1 + " simplified = " + f1.simplify());
    System.out.println(f2 + " simplified = " + f2.simplify());
    System.out.println(f3 + " simplified = " + f3.simplify());

    // show that f1, f2, f3 haven't changed
    System.out.println("f1 = " + f1);
    System.out.println("f2 = " + f2);
    System.out.println("f3 = " + f3);

    // arithmetic
    System.out.println(f1 + " + " + f2 + " = " + f1.add(f2));
    System.out.println(f1 + " - " + f2 + " = " + f1.subtract(f2));
    System.out.println(f1 + " * " + f2 + " = " + f1.multiply(f2));
    System.out.println(f1 + " / " + f2 + " = " + f1.divide(f2));
    System.out.println();

    System.out.println(f2 + " + " + f3 + " = " + f2.add(f3));
    System.out.println(f2 + " - " + f3 + " = " + f2.subtract(f3));
    System.out.println(f2 + " * " + f3 + " = " + f2.multiply(f3));
    System.out.println(f2 + " / " + f3 + " = " + f2.divide(f3));
    System.out.println();

    // test 'division by zero' handling
    Fraction zero = new Fraction();
    System.out.println(f2 + " / " + zero + " = " + f2.divide(zero));
  }
}

Результаты должны отображаться следующим образом:

4/6 simplified = 2/3
75/175 simplified = 3/7
-6/17 simplified = -6/17
f1 = 4/6
f2 = 75/175
f3 = -6/17
4/6 + 75/175 = 23/21
4/6 - 75/175 = 5/21
4/6 * 75/175 = 2/7
4/6 / 75/175 = 14/9

75/175 + -6/17 = 9/119
75/175 - -6/17 = 93/119
75/175 * -6/17 = -18/119
75/175 / -6/17 = -17/14 (THIS SHOWS UP AS 0/1 INSTEAD...)

75/175 / 0/1 = 0/1 

Я знаю, что это что-то в методе Divide, потому что, когда я изменил -6/17 только на 6/17 в последнем, он работал и печатал 17/14 в упрощенном виде. Я просто понятия не имею, что в методе Divide не работает с отрицательными дробями. Может быть, я могу что-то добавить, чтобы помочь с этой проблемой? Заранее спасибо.


person mch5904    schedule 15.07.2015    source источник
comment
Первый ответ здесь может помочь вам, братан, math.stackexchange.com/questions/285452/   -  person wuno    schedule 15.07.2015


Ответы (2)


In divide(),

public Fraction divide (Fraction f){
   int den1 = this.denominator;
   int den2 = f.denominator;
   int num1 = this.numerator;
   int num2 = f.numerator;

   int num3 = num1 * den2;
   int den3 = den1 * num2;

   Fraction f2 = new Fraction (num3, den3);
   ...

Предположим, что this положительное, а f отрицательное. По вашему предположению,

den1 > 0
den2 > 0
num1 > 0
num2 < 0
num3 = num1 * den2 > 0
den3 = den1 * num2 < 0

Однако, когда new Fraction(num3, den3) вызывает set(),

public boolean set(int n, int d) {
    if (d > 0) {
       numerator = n;
       denominator = d;
       return true;
    } else
       return false;
}

Когда знаменатель меньше 0, вы вернули false, что запрещает установку значения в класс.

Вы можете поменять местами знаки как для числителя, так и для знаменателя, вместо того, чтобы просто возвращать false.

person timrau    schedule 15.07.2015
comment
Когда я попытался поменять местами знаки числителя и знаменателя в set(), он вывел 75/175 / 6/17 = 17/14 для последней задачи деления. Поскольку это изменило знак -6/17 на 6/17 для всех из них, я попытался инвертировать знак числителя перед умножением на Divide(). Это сработало, за исключением знака ответа. У меня 75/175 / -6/17 = 17/14. Как я могу изменить знак ответа на правильный ответ -17/14? - person mch5904; 15.07.2015
comment
Хорошо, я понял это! Я поставил if(num2 < 0){ num2 = 0-num2; num3 = 0 - num3; } между двумя задачами на умножение в Divide() и напечатал -17/14. Спасибо за помощь! - person mch5904; 15.07.2015

Попробуйте изменить свой метод set на это:

public boolean set(int n, int d) {
    if (d > 0) {
       numerator = n;
       denominator = d;
       return true;
    } 
    else if (d < 0) {
        numerator = n * -1;
        denominator = d * -1;
        return true;
    }
    else
       return false;
}

Без второго утверждения if set будет оцениваться как ложное для дробей с отрицательным демонинатором. В таких случаях Fraction, возвращаемый методом divide, будет равен 0/1.

person jchamp    schedule 15.07.2015