Ponto flutuante pra fração, como?

Eae pessoal,

Existe algum método implementado que retorne a fração(caso exista) de um número em ponto flutuante. Preciso para saída de tela e para a perca de precisao. Gostaria de saber pois senão terei que implementar algo.

Muito obrigaado

seja mais claro vc quer 18,69 ?

Digamos que você tenha o número

double d = 18.69;

Se você quer o valor e = 0.69, então você pode fazer:

double e = d - Math.floor (d);

Acho que me expliquei mal…

O que eu queria era algo do tipo.

tranformar 1.33333333… para 4/3 por exemplo

Ou para string “4/3” ou retornando os valores do denominador e numerador

Existe algo implementado para isso ???

Sendo rigoroso, isso não é possível em Java ou outra linguagem que use ponto-flutuante, a menos que faça algumas “aproximações”.

É que quando você divide 4.0 por 3.0, o resultado em Java é

1,3333333333333332593184650249896

que é o número

6004799503160661 / 4503599627370496

(não parece nem um pouco com 4/3 …)

Para conseguir chegar ao resultado que você quer (4 / 3) é necessário usar alguns algoritmos especiais (não sei exatamente quais).

Moral:

Para trabalhar com frações, não se pode em momento algum convertê-las para “double” ou “float”. Você tem de trabalhar desde o começo com frações.

Eu estava pensando em implementar algo tipo, pegaria o nro 0.75 e iria multiplicando por 10 e dividindo por 10 ateh uns 10 digitos depois da virgula. dai ficaria assim por exemplo

75 / 100 e apartir desse número tentaria simplifica -lo ao máximo

Sei lá tb se funcionaria isso, só queria saber como, pq ate as calculadoras fazem isso, transformam um nro com virgula em fração.

Mas mesmo assim, valeu por toda ajuda !

http://www.mathworks.com/access/helpdesk/help/techdoc/ref/rats.html tem um algoritmo como o que você deseja.

Puuu, vou olhar com mais calma quando eu sair dessas minhas loucuras de provas.

Mas ta guardado nos meus favoritos, a principio muito bom !

Valeu !

Parece que funciona direitinho, testei com seu 4/3 e deu o resultado rapidinho.

Interessante.

Implementei o tal algoritmo (é claro que deve ter alguns bugs), e para certas divisões (como 2005.0 / 2006.0) o valor dá bem diferente do esperado.

import java.math.*;
import java.util.*;

class Rational {
    private BigInteger numerator;
    private BigInteger denominator;
    public Rational (long n) {
        numerator = new BigInteger (Long.toString (n)); denominator = BigInteger.ONE;
    }
    public Rational (BigInteger n, BigInteger d) {
        numerator = n; denominator = d;
        simplify();
    }
    public Rational (Rational r) {
        numerator = r.numerator;
        denominator = r.denominator;
    }
    public Rational () {
        numerator = BigInteger.ZERO;
        denominator = BigInteger.ONE;
    }
    public String toString() { return numerator + "/" + denominator; }
    
    public static Rational add (Rational x, Rational y) {
        return new Rational (
            x.numerator.multiply (y.denominator).add(y.numerator.multiply (x.denominator)),
            x.denominator.multiply (y.denominator));
    }

    public static Rational sub (Rational x, Rational y) {
        return new Rational (
            x.numerator.multiply (y.denominator).subtract(y.numerator.multiply (x.denominator)),
            x.denominator.multiply (y.denominator));
    }

    public static Rational mul (Rational x, Rational y) {
        return new Rational (
            x.numerator.multiply (y.numerator),
            x.denominator.multiply (y.denominator));
    }
    public static Rational div (Rational x, Rational y) {
        return new Rational (
            x.numerator.multiply (y.denominator),
            x.denominator.multiply (y.numerator));
    }
    public static Rational inv (Rational x) {
        return new Rational (x.denominator, x.numerator);
    }
    private void simplify () {
        if (!numerator.equals (BigInteger.ZERO)) {
            BigInteger gcd = numerator.gcd (denominator);
            numerator = numerator.divide(gcd);
            denominator = denominator.divide(gcd);
        } else {
            denominator = BigInteger.ONE;
        }
    }
    public double doubleValue() {
        return numerator.doubleValue() / denominator.doubleValue();
    }        

}

class Rat {
    public Rational rat (double x) {
        long[] d = new long[21];
        int k = d.length-1;
        for (int i = 0; i < d.length; ++i) {
            d [i] = (long) x; // picking off the integer part
            if (x - d[i] < 1E-10) {
                k = i;
                break;
            }
            x = 1 / (x - d[i]);
        }
        //-- Uma vez que temos os termos, devemos achar o valor correto        
        // Calculando 1/dk, somando com d[k-1], invertendo e assim por diante.
        Rational q = new Rational (d[k]);
        for (int i = k; i >= 1; --i) {
            q = Rational.inv (q); 
            q = Rational.add (q, new Rational (d[i-1])); 
        }
        return q;
    }
 
    
    public static void main(String[] args) {
        Rat r = new Rat();
        Rational f;
        f = r.rat (4.0 / 3.0); // 4/3
        System.out.println (f);
        f = r.rat (11.0 / 7.0); // 11/7
        System.out.println (f);
        f = r.rat (7.0 / 1999.0); // 7/1999
        System.out.println (f);
        f = r.rat (0.75); // 3/4
        System.out.println (f);
        //-- Note que o algoritmo pode desembestar:
        f = r.rat (2005.0/2006.0); // 14374494523137244723793128/14381663847088933356788119
        System.out.println (f);
        
        //-- Para valores famosos...
        f = r.rat (Math.sqrt(2.0)); // 54608393/38613965
        System.out.println (f); 
        f = r.rat (Math.PI); // 42581509225984/13554115355257
        System.out.println (f);
        f = r.rat (Math.E); // 325368125/119696244
        System.out.println (f);
        f = r.rat (Math.log (10)); // 69333509878/30111160751
        System.out.println (f);
        f = r.rat ((Math.sqrt (5.0) + 1.0) / 2.0); // 17711/10946
        System.out.println (f);
    }
}

:shock:
Nem tive tempo para olhar a página e vc ja implementou…

Muito bom !

Assim que acabar minhas 13546847351654 provas eu olho :wink:

:thumbup: