0

I am having trouble with floating points. A the double . 56 in Java, for example, might actually be stored as .56000...1.

I am trying to convert a decimal to a fraction. I tried to do this using continued fractions

Continuous Fractions

but my answers using that method were inaccurate due to how to computer stored and rounded decimals.

I tried an alternative method:

public static Rational rationalize(double a){
        if(a>= 1){
        //throw some exception
    }
    String copOut = Double.toString(a);

    int counter = 0;
    System.out.println(a);
    while(a%1 != 0 && counter < copOut.length() - 2){
        a *= 10;
        counter++;
    }
    long deno = (long)Math.pow(10,counter);//sets the denominator
    Rational frac = new Rational((long)a,deno)//the unsimplified rational number
    long gcd = frac.gcd();
    long fnum = frac.getNumer();//gets the numerator 
    long fden = frac.getDenom();//gets the denominator
    frac = new Rational(fnum/gcd, fden/gcd);
    return frac;    
}

I am using the string to find the length of the decimal to determine how many time I should multiply by 10. I later truncate the decimal. This gets me the right answer, but it does not feel like the right approach? Can someone suggest the 'correct' way to do this?

Community
  • 1
  • 1
Zhv Z
  • 53
  • 5
  • The first problem here is that the *input* is `double.` So you're already losing precision before any of your code even executes. Have a think about `BigDecimal.` – user207421 Feb 18 '14 at 05:31

1 Answers1

1

Actually you are doing great.. But this will fail if the Input is something about 11.56. Here you need to to do copOut.length() - 3.

To make it dynamic use String#split()

String decLength = copOut.split("\\.")[1]; //this will result "56" (Actual string after decimal)

Now you just need to do only

while(a%1 != 0 && counter < decLength.length()){
        a *= 10;
        counter++;
    }

If you want to remove the loop then use

long d = (long)Math.pow(10,decLength.length());
 a=a*d;
AJ.
  • 4,526
  • 5
  • 29
  • 41