Вопрос прост для понимания, но для жизни я не могу понять, как его реализовать:
Как мне перейти от приближения десятичной дроби к фактической дроби (т. е. к двум целым числам)? например учитывая 0,666666666667, как я могу получить 2/3 (используя определенную точность)?
Я знаю, что могу преобразовать 0,666666666667 в 666666666667/10000000..., и я знаю, что я могу уменьшить дробь, используя GCD, но эти методы не решают проблему, потому что 6667/10000 не уменьшается до 2/3.
Я хочу знать, как взять какое-то десятичное число, например 0,6666667, и сказать: «Это, вероятно, 2/3».
Любые идеи?
У меня есть код, работающий для сокращения дробей, но опять же, не для задачи выше:
public class Fraction implements Comparable<Fraction> {
private static Map<Fraction, Long> gcdMemo = new HashMap<>();
public final long n;
public final long d;
public Fraction(long n, long d) {
this.n = n; this.d = d;
}
public Fraction multiply(Fraction f) {
return new Fraction(f.n * this.n, f.d * this.d).reduced();
}
public Fraction subtract(Fraction f) {
return this.add(new Fraction(-f.n, f.d));
}
public Fraction abs() {
return new Fraction(Math.abs(n), Math.abs(d));
}
public Fraction add(Fraction f) {
long newN0 = this.n * f.d;
long newD0 = this.d * f.d;
long newN1 = f.n * this.d;
return new Fraction(newN0 + newN1, newD0).reduced();
}
public static long gcd(long a, long b) {
if (gcdMemo.containsKey(new Fraction(a, b))) {
return gcdMemo.get(new Fraction(a, b));
}
if(a == 0 || b == 0) return a + b; // base case
long result = gcd(b, a % b);
Fraction f = new Fraction(a, b);
if (!gcdMemo.containsKey(f)) {
gcdMemo.put(f, result);
}
return result;
}
public Fraction reduced() {
long gcd = gcd(n, d);
return new Fraction(n / gcd, d /gcd);
}
public int compareTo(Fraction f) { /*...*/ }
public int hashCode() { /**/ }
public boolean equals(Object obj) { /*...*/ }
public String toString() { /*...*/ }
}
Кроме того, я знаю, что это возможно, потому что мой TI-84 может это сделать :D