我有两个类:分数和测试。我已经很好地使用了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
。请指点我的事。
答案 0 :(得分:3)
问题在于getNumerator()
,getDenominator()
和gcd
会返回int
。因此,equals
方法中的除法是以整数形式完成的:
double fractionFloatValue = (f.getNumerator()/gcd1) / (f.getDenominator()/gcd1);
...
double fractionFloatValue2 = (this.getNumerator()/gcd2) / (this.getDenominator()/gcd2);
fractionFloatValue
和fractionFloatValue2
的值实际上是整数,即使它们被分配给double
类型的变量。 1/3
和1/2
都是适当的分数,因此在两种情况下整数除法的计算结果为零。这就是为什么equals
在两种情况下都会返回true
的原因。
有两种方法可以解决这个问题:
gcd1
和gcd2
声明为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);
现在有效了。