Alterar Decimal para Fração em JS

Jan 11 2023
É claro que existem muitos algoritmos sofisticados fora deste artigo, desde livros, resultados de pesquisas até laboratórios de supercomputadores. Mas temos apenas um computador ou laptop e queremos converter um número decimal em um par de frações que melhor represente o número decimal.
Foto de Volkan Olmez no Unsplash

decToFrac(0.1625)
// get [13, 8] or simply 13 / 8

É claro que existem muitos algoritmos sofisticados fora deste artigo, desde livros, resultados de pesquisas até laboratórios de supercomputadores. Mas temos apenas um computador ou laptop e queremos converter um número decimal em um par de frações que melhor represente o número decimal. Por que uso a palavra “representar”? Porque quando recebemos um número decimal tão único, entre as muitas frações alternativas que podemos procurar, não é certo que haja um que seja realmente perfeito para corresponder a esse número decimal.

Eu, que sou novo em matemática, apenas com curiosidade e um pouco de conhecimento da linguagem JavaScript, adoraria criar uma função que pudesse converter um número decimal de volta para uma fração. Aqui está o código JS que fiz:

decToFrac = dec =>
  [...Array(1000).keys()].flatMap(
    i => [...Array(1000).keys()].map(
      j => [
        i + 1, j + 1, (i + 1) / (j + 1),
        Math.abs(((i + 1) / (j + 1)) - dec)
      ]
    )
  ).sort((a, b) => a[3] - b[3])[0].slice(0, 2)

É claro que a função acima não é o algoritmo mais eficiente para se trabalhar, mas pelo menos podemos tentar 1 milhão de possibilidades para descobrir qual delas está mais próxima do valor decimal que estamos almejando.

decToFrac( 23.689817948712386928365235 )
// get [687, 29] in 2 seconds

687 / 29 // get 23.689655172413794
         // accurate to 3 decimals

Na segunda linha está um exemplo de como se contarmos 687 / 29, o console mostrará o resultado 23.689655172413794com 15 casas decimais. Se compararmos com o número decimal que demos à função anteriormente, fica claro que os dois decimais não são exatamente iguais. Mas pelo menos esta função é capaz de calcular com precisão até 3 casas decimais. Se suas necessidades variam do campo da economia à engenharia de construção, talvez essa precisão de 3 dígitos seja suficiente para satisfazer suas necessidades de trabalho. Mas não espere que esta função seja a única solução para suas pesquisas em matemática pura ou física, pois elas certamente exigirão uma precisão muito maior.

//            16 digits     /    16 digits
decToFrac( 7528365409872894 / 9876598265498238 )
// get [747, 980] still in 2 seconds

E se quisermos que essa função produza números mais precisos? Claro que você pode, simplesmente modificando a função decToFracacima, estendendo a matriz existente. Exemplos como este:

decToFrac = dec =>
  [...Array(10000).keys()].flatMap( // from 1,000 to 10,000
    i => [...Array(1000).keys()].map(
      j => [
        i + 1, j + 1, (i + 1) / (j + 1),
        Math.abs(((i + 1) / (j + 1)) - dec)
      ]
    )
  ).sort((a, b) => a[3] - b[3])[0].slice(0, 2)

Obrigado, e pode ser útil para você.