Search code examples
javapython-3.xfractions

converting decimal into fractions, java and python gives different output


i'm trying to convert decimals into fractions. my program works just fine for other numbers. however when trying to find the numerator and denominator for 1.0923059908040425e-33,

java gives 1/9 where as python gives 0.

this is my code for java:

class Rational {
public static void main(String[] args) {
     println(getDenominator(convertDecimalToFraction(1.0923059908040425e-33)));
}

public static int getNumerator(String fraction) {
    return Integer.valueOf(fraction.substring(0, fraction.indexOf(".")));
}
public static int getDenominator(String fraction) {
    fraction = fraction.substring(fraction.indexOf("/") + 1);
    return Integer.valueOf(fraction.substring(0, fraction.indexOf(".")));
}

static private String convertDecimalToFraction(double x){
    if (x < 0){
        return "-" + convertDecimalToFraction(-x);
    }
    double tolerance = 1.0E-6;
    double h1=1; double h2=0;
    double k1=0; double k2=1;
    double b = x;
    do {
        double a = Math.floor(b);
        double aux = h1; h1 = a*h1+h2; h2 = aux;
        aux = k1; k1 = a*k1+k2; k2 = aux;
        b = 1/(b-a);
    } while (Math.abs(x-h1/k1) > x*tolerance);

    return h1+"/"+k1;
}
}

and this is python:

print(fractions.Fraction(1.0923059908040425e-33).limit_denominator())

i think there's problem in my java code because i'm expecting 0 as correct output, but there is built-in library available for Fractions, and i don't want to use any third-party libraries.

java code works on mostly all inputs. only problem with this one input. please point me error if any. i would really appreciate if you can provide me with a method or logic that can solve this problem


print(fractions.Fraction(1.0923059908040425e-33)) gives 6385627976105849/5846006549323611672814739330865132078623730171904

after adding limit_denominator, it becomes 0. i don't know what is going on here..


Solution

  • Well a bit a debugging would immediately show what happens. convertDecimalToFraction returns "1.0/9.15494383825455E32" which is not stupid, but getDenominator just ignores the E32. You should mimic the limit_denominator from Python and say that if x<tolerance then the returned value shall be "0./1.":

    static private String convertDecimalToFraction(double x){
        if (x < 0){
            return "-" + convertDecimalToFraction(-x);
        }
        double tolerance = 1.0E-6;
        if (x < tolerance) {
            return "0./1.";
        }
        double h1=1; double h2=0;
        double k1=0; double k2=1;
        double b = x;
        do {
            double a = Math.floor(b);
            double aux = h1; h1 = a*h1+h2; h2 = aux;
            aux = k1; k1 = a*k1+k2; k2 = aux;
            b = 1/(b-a);
        } while (Math.abs(x-h1/k1) > x*tolerance);
    
        return h1+"/"+k1;
    }