Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Double to fraction in Java

So what I'm trying to do is convert double to rational number. I check how many digits there is after decimal point and I want to save the number 123.456 as 123456 / 1000, for example.

public Rational(double d){      
    String s = String.valueOf(d);
    int digitsDec = s.length() - 1 - s.indexOf('.');        

    for(int i = 0; i < digitsDec; i++){
        d *= 10;
    }

    System.out.println((int)d); //checking purposes
}   

However, for the number 123.456 I get a round off error and the result is 123455. I guess it'd be possible to fix this with BigDecimal but I can't get it to work. Also, having calculated what rational number it would be, I would like to call another constructor with parameters (int numerator, int denominator) but I can't obviously call the constructor in the line where println is now. How should I do this?

like image 727
Neutrino Avatar asked Dec 08 '22 18:12

Neutrino


1 Answers

For the first part of the question, Java is storing .6 as .5999999 (repeating). See this output:

(after first multiply): d=1234.56
(after second multiply): d=12345.599999999999
(after third multiply): d=123455.99999999999

One fix is to use d = Math.round(d) immediately after your loop finishes.

public class Rational {

     private int num, denom;

     public Rational(double d) {
          String s = String.valueOf(d);
          int digitsDec = s.length() - 1 - s.indexOf('.');        

          int denom = 1;
          for(int i = 0; i < digitsDec; i++){
             d *= 10;
             denom *= 10;
          }
          int num = (int) Math.round(d);

          this.num = num; this.denom = denom;
     }

     public Rational(int num, int denom) {
          this.num = num; this.denom = denom;
     }

     public String toString() {
          return String.valueOf(num) + "/" + String.valueOf(denom);
     }

     public static void main(String[] args) {
          System.out.println(new Rational(123.456));
     }
}

It works - try it.

For the second part of your question...

In order to call the second constructor from the first, you can use the "this" keyword

this(num, denom)

But it has to be the very first line in the constructor... which doesn't make sense here (we have to do some calculations first). So I wouldn't bother trying to do that.

like image 156
ktm5124 Avatar answered Dec 11 '22 07:12

ktm5124