web-dev-qa-db-fra.com

Comment convertir des nombres décimaux en fractions?

Ce dont j'ai besoin pour convertir des nombres décimaux en fractions. Il est facile de convertir à 10 pieds.

1.5 => 15/10

Cela peut se faire via ce code:

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(1.5));
    }
}

Mais ce que je veux c'est

1.5 => 3/2

et je ne comprends pas comment procéder. Ma question n'est pas une duplication. Parce que l'autre question connexe est C #. C'est Java.

7
pippi longstocking

Vous devriez trouver le plus grand commun diviseur des nombres obtenus et en diviser le numérateur et le dénominateur.

Voici une façon de le faire:

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);
        int g = gcd(num, denom);
        this.num = num / g;
        this.denom = denom /g;
    }

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

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

    public static int gcd(int num, int denom) {
          ....
    }

    public static void main(String[] args) {
        System.out.println(new Rational(1.5));
    }
}
9
Hristo93
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;
}

J'ai eu cette réponse de ici . Tout ce que je devais faire était de convertir sa réponse en Java.

6
Matthew556

Étant donné double x> = 0, int p, int q, trouver p/q comme approximation la plus proche:

  • itérer sur q à partir de 1, déterminer p ci-dessus et ci-dessous; vérifier les écarts

Donc (non testé):

public static Rational toFraction(double x) {
    // Approximate x with p/q.
    final double eps = 0.000_001;
    int pfound = (int) Math.round(x);
    int qfound = 1;
    double errorfound = Math.abs(x - pfound);
    for (int q = 2; q < 100 && error > eps; ++q) {
        int p = (int) (x * q);
        for (int i = 0; i < 2; ++i) { // below and above x
            double error = Math.abs(x - ((double) p / q));
            if (error < errorfound) {
                pfound = p;
                qfound = q;
                errorfound = error;
            }
            ++p;
        }
    }
    return new Rational(pfound, qfound);
}

Vous pouvez l'essayer pour Math.PI et E.

2
Joop Eggen

J'ai préparé une solution à cette question. Peut-être que cela ressemble à un primitif mais en travaillant. J'ai testé plusieurs nombres décimaux. Au moins, il peut convertir 1,5 à 3/2 :)

public String kesirliYap(Double sayi){
    String[] a=payPaydaVer(sayi);
    return a[0]+"/"+a[1];
}
public String[] payPaydaVer(Double sayi){
long pay;
long payda;

  DecimalFormat df=new DecimalFormat("#");
    df.setRoundingMode(RoundingMode.FLOOR);
    String metin=sayi.toString();        
    int virguldenSonra=(metin.length() -metin.indexOf("."))-1;
    double payyda=Math.pow(10,virguldenSonra);
    double payy=payyda*sayi;
    String pays=df.format(payy);
    String paydas=df.format(payyda);
    pay=Long.valueOf(pays);
    payda=Long.valueOf(paydas);


   String[] kesir=sadelestir(pay,payda).split(",");

   return kesir;
}

private String sadelestir(Long pay,Long payda){
    DecimalFormat df=new DecimalFormat("#");
    df.setRoundingMode(RoundingMode.FLOOR);
    Long a=pay<payda ? pay : payda;
    String b = "",c = "";
    int sayac=0;
    for(double i = a;i>1;i--){
      double payy=pay/i;
      double paydaa=payda/i;
      String spay=df.format(payy);
      String spayda=df.format(paydaa);
      Long lpay=Long.valueOf(spay);
      Long lpayda=Long.valueOf(spayda);
      if((payy-lpay)==0&&(paydaa-lpayda)==0){
          b=df.format(pay/i);
          c=df.format(payda/i);
          sayac++;
          break;
      }

    }

    return sayac>0 ?  b+","+c:pay+","+payda;
}
1
Orhan

Voici un algorithme simple:

numerato = 1.5
denominator = 1;

while (!isInterger(numerator*denominator))
do
    denominator++;
done

return numerator*denominator + '/' + denominator


// => 3/2

Il vous suffit de l'implémenter en Java + pour implémenter la isInteger(i)i est une float.

1
Rémi Becheras

Non seulement pour le nombre décimal 1.5, mais pour tous, vous pouvez utiliser les étapes suivantes:

  1. Rechercher Nombre de chiffres décimaux:

    double d = 1.5050;//Example I used

    double d1 = 1; 

    String text = Double.toString(Math.abs(d));

    int integerPlaces = text.indexOf('.');

    int decimalPlaces = text.length() - integerPlaces - 1;

    System.out.println(decimalPlaces);//4

  2. Puis convertir en entier: 

    static int ipower(int base, int exp) {

        int result = 1;
        for (int i = 1; i <= exp; i++) {
            result *= base;           
        }            
        return result;
    }
    

    //using the method

    int i = (int) (d*ipower(10, decimalPlaces));

    int i1 = (int) (d1*ipower(10, decimalPlaces));

    System.out.println("i=" + i + " i1 =" +i1);//i=1505 i1 =1000

  3. Puis trouver le facteur commun le plus élevé 

    private static int commonFactor(int num, int divisor) {

        if (divisor == 0) {
            return num;
        }
    
        return commonFactor(divisor, num % divisor);
    }
    

//using common factor

int commonfactor = commonFactor(i, i1);

System.out.println(commonfactor);//5

  1. Enfin imprimer les résultats:

    System.out.println(i/commonfactor + "/" + i1/commonfactor);//301/200

Ici vous pouvez trouver:

  public static void main(String[] args) {

        double d = 1.5050;
        double d1 = 1;

        String text = Double.toString(Math.abs(d));
        int integerPlaces = text.indexOf('.');
        int decimalPlaces = text.length() - integerPlaces - 1;

        System.out.println(decimalPlaces);
        System.out.println(ipower(10, decimalPlaces));

        int i = (int) (d*ipower(10, decimalPlaces));
        int i1 = (int) (d1*ipower(10, decimalPlaces));      

        System.out.println("i=" + i + " i1 =" +i1);

        int commonfactor = commonFactor(i, i1);
        System.out.println(commonfactor);

        System.out.println(i/commonfactor + "/" + i1/commonfactor);


    }

    static int ipower(int base, int exp) {
        int result = 1;
        for (int i = 1; i <= exp; i++) {
            result *= base;           
        }

        return result;
    }

    private static int commonFactor(int num, int divisor) {
        if (divisor == 0) {
            return num;
        }
        return commonFactor(divisor, num % divisor);
    }

J'ai essayé d'ajouter ceci en tant que modification, mais cela a été refusé. Cette réponse est issue de answer de @ Hristo93 mais termine la méthode gcd:

public class DecimalToFraction {

    private int numerator, denominator;

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

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

        int numerator = (int) Math.round(decimal);
        int gcd = gcd(numerator, denominator); 

        this.numerator = numerator / gcd;
        this.denominator = denominator /gcd;
    }

    public static int gcd(int numerator, int denom) {
        return denominator == 0 ? numerator : gcm(denominator, numerator % denominator);
    }

    public String toString() {
        return String.valueOf(numerator) + "/" + String.valueOf(denominator);
    }

    public static void main(String[] args) {
        System.out.println(new Rational(1.5));
    }
}
1
John R Perry

Y compris la méthode pour trouver le facteur commun le plus élevé et la modification de la méthode toString, résout votre question, je suppose.

public String toString() {
        int hcf = findHighestCommonFactor(num, denom);
        return (String.valueOf(num/hcf) + "/" + String.valueOf(denom/hcf));

    }

    private int findHighestCommonFactor(int num, int denom) {
        if (denom == 0) {
            return num;
        }
        return findHighestCommonFactor(denom, num % denom);
    }
1
Abhiram Kulkarni