Как преобразовать .66667 в дробь 2/3?

Вопрос прост для понимания, но для жизни я не могу понять, как его реализовать:

Как мне перейти от приближения десятичной дроби к фактической дроби (т. е. к двум целым числам)? например учитывая 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


person Rico Kahler    schedule 03.05.2017    source источник