比较两个分数

时间:2015-11-08 03:39:56

标签: java

我有两个类:分数和测试。我已经很好地使用了Fraction类,但是类Test有一些问题。

我想允许用户输入分数并存储在ArrayList中,用户可以通过选择数组的索引来比较数组中的两个分数。但是,当我比较两个分数时,它不能很好地工作!

class Fraction:

class Fraction {

    private int numerator;
    private int denominator;

    Fraction(int n, int d) {
        numerator = n;
        denominator = d;
    }

    public Fraction(int n) {
        this(n, 1);
    }

    public Fraction() {
        numerator = 0;
        denominator = 1;
    }

    public int getNumerator() {
        return numerator;
    }

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

    public int getDenominator() {
        return denominator;
    }

    public void setDenominator(int denominator) {
        this.denominator = denominator;
    }

    public void display() {
        String s =  this.getNumerator() + "/" + this.getDenominator();
        System.out.println(s);
    }

    public double evaluate() {
        double n = numerator; 
        double d = denominator;
        return (n / d);
    }

    public boolean isEquals(Fraction f){
        int gcd1 = gcd(f.getNumerator(), f.getDenominator());
        double fractionFloatValue = (f.getNumerator()/gcd1) / (f.getDenominator()/gcd1); 
        int gcd2 = gcd(this.getNumerator(), this.getDenominator());
        double fractionFloatValue2 = (this.getNumerator()/gcd2) / (this.getDenominator()/gcd2);
        return (fractionFloatValue == fractionFloatValue2) ? true : false;

    }

    public Fraction add(Fraction f2) {
        Fraction r = new Fraction((numerator * f2.denominator)
                + (f2.numerator * denominator), (denominator * f2.denominator));
        return r;
    }

    static private int gcd(int x, int y) {
        return y == 0 ? x : gcd(y, x % y);
    }

    public static String asFraction(int x, int y) {
        int gcd = gcd(x, y);
        return (x / gcd) + "/" + (y / gcd);
    }

    /*public static void main(String[] argv) {

        Fraction f0 = new Fraction();
        Fraction f1 = new Fraction(3);
        Fraction f2 = new Fraction(20, 60);
        Fraction f3 = new Fraction(1, 3);

        System.out.println("--------------Testing constructors--------------");
        f0.display();
        f1.display();
        f2.display();
        System.out.println("--------------Test if two fractions is equal--------------");
        System.out.println(f2.isEquals(f1));
    }*/
}

和类测试:

import java.util.ArrayList;
import java.util.Scanner;

public class Test {

    public static void enterFraction(){
        ArrayList<Fraction> arr = new ArrayList<Fraction>();
        Scanner scanner = new Scanner(System.in);
        boolean check = false;
        int i = 1;
        while(!check){
            System.out.println("Enter fraction"+i+":");
            Fraction f = new Fraction();
            System.out.println("Enter Numerator: ");
            int numerator = scanner.nextInt();
            scanner.nextLine();
            f.setNumerator(numerator);
            System.out.println("Enter Denominator: ");
            int denominator = scanner.nextInt();
            scanner.nextLine();
            f.setDenominator(denominator);
            System.out.println("Your fraction"+i+" is: "+f.getNumerator()+"/"+f.getDenominator());
            arr.add(f);
            System.out.println("Want to compare fractions? (Y/Yes or N/No)");
            String compareRequest = scanner.nextLine();
            if(compareRequest.equalsIgnoreCase("y")){
                System.out.println("Choose your target fraction!!! (enter the index of the array)");
                int position = scanner.nextInt();
                scanner.nextLine();
                Fraction targetFraction = arr.get(position);
                targetFraction.display();
                System.out.println("Choose your second fraction to compare!!! (enter the index of the array)");
                int position2 = scanner.nextInt();
                scanner.nextLine();
                Fraction secondFraction = arr.get(position2);
                secondFraction.display();
                boolean compareTwoFractions = secondFraction.isEquals(targetFraction);
                if(compareTwoFractions == true){
                    System.out.println("Two fractions are equal");
                }
                else if(compareTwoFractions == false){
                    System.out.println("Two fractions are not equal");
                }           
            }   
            i++;
            System.out.println("Do you want to enter more fraction? (Y/Yes or N/No)");
            String checkRequest = scanner.nextLine();
            if(checkRequest.equalsIgnoreCase("n")){
                check = true;
            }
        }   
    }

    public static void main(String[] args){
        enterFraction();
    }
}

我这样输入:

Enter fraction1:
Enter Numerator: 
2
Enter Denominator: 
4
Your fraction1 is: 2/4
Want to compare fractions? (Y/Yes or N/No)
n
Do you want to enter more fraction? (Y/Yes or N/No)
y
Enter fraction2:
Enter Numerator: 
1
Enter Denominator: 
3
Your fraction2 is: 1/3
Want to compare fractions? (Y/Yes or N/No)
y
Choose your target fraction!!! (enter the index of the array)
0
2/4
Choose your second fraction to compare!!! (enter the index of the array)
1
1/3
Two fractions are equal
Do you want to enter more fraction? (Y/Yes or N/No)

你认为它不起作用,2/4 == 1/3。请指点我的事。

2 个答案:

答案 0 :(得分:3)

问题在于getNumerator()getDenominator()gcd会返回int。因此,equals方法中的除法是以整数形式完成的:

double fractionFloatValue = (f.getNumerator()/gcd1) / (f.getDenominator()/gcd1); 
...
double fractionFloatValue2 = (this.getNumerator()/gcd2) / (this.getDenominator()/gcd2);

fractionFloatValuefractionFloatValue2的值实际上是整数,即使它们被分配给double类型的变量。 1/31/2都是适当的分数,因此在两种情况下整数除法的计算结果为零。这就是为什么equals在两种情况下都会返回true的原因。

有两种方法可以解决这个问题:

  • gcd1gcd2声明为double。这将迫使分裂为double;不幸的是,你的代码会遭受平等的双重比较,这本身就是不精确的,或者
  • n1/d1 == n2/d2时使用身份n1*d2 == n2*d1。这样可以消除除法,因此您可以在比较中获得完美的精确度,直到溢出为止(如果对乘法结果使用long,则不会因为使用的约束而溢出)。

答案 1 :(得分:1)

我更改了@dasblinkenlight提到的两行:

double fractionFloatValue = ((f.getNumerator()/gcd1)*1.0) / (f.getDenominator()/gcd1);

double fractionFloatValue2 = ((this.getNumerator()/gcd2)*1.0) / (this.getDenominator()/gcd2);

现在有效了。