Os Rational numbers são frações com um numerador inteiro dividido por um denominador inteiro.
Por exemplo, podemos guardar 2//3 como uma fração exata em vez do valor aproximado Float64 0.6666...
A vantagem é que (exceto no caso extremo de overflow de inteiros) um número racional permanece exato, evitando os erros de arredondamento que muitas vezes são inevitáveis com números de vírgula flutuante.
Os números racionais são um tipo numérico bastante simples e funcionam, em grande parte, como seria de esperar. Como são um tipo padrão em Julia desde as primeiras versões, a maioria das funções aceita-os da mesma forma que aceita inteiros e números de vírgula flutuante.
Criar um número racional é tão simples como usar // entre dois inteiros.
julia> 3//4
3//4
julia> a = 3; b = 4;
julia> a//b
3//4
Os fatores comuns são removidos automaticamente, convertendo a fração na sua "forma irredutível": os menores inteiros que representam a fração com exatidão e com um denominador não negativo.
julia> 5//15
1//3
julia> 5//-15
-1//3
Os arithmetic operators habituais + - * / ^ % funcionam com racionais, essencialmente da mesma forma que com outros tipos numéricos.
Podem incluir-se inteiros e outros Rational, e o resultado será um Rational.
Incluir um float na expressão dá um resultado do tipo float, com uma consequente (e possível) perda de precisão.
Se quiseres um float, basta usar a função float() para converter um racional.
É bastante normal usar números racionais para preservar a precisão ao longo de um cálculo extenso e, no fim, converter para um número de vírgula flutuante.
julia> 3//4 + 1//3 # addition
13//12
julia> 3//4 * 1//3 # multiplication
1//4
julia> 3//4 / 1//3 # division
9//4
julia> 3//4 ^ 2 # exponentiation
3//16
julia> 3//4 + 5 # rational and int => rational
23//4
julia> 3//4 + 5.3 # rational and float => float
6.05
julia> float(3//4) # casting
0.75
Em Julia, os números racionais são apenas números. Normalmente, o compilador converte os tipos conforme for necessário.
No entanto, tem em atenção que as comparações funcionam para frações com uma representação decimal finita:
julia> 3//4 == 0.75
true
julia> 3//4 < 0.74
false
Mas, fora desses casos, um Rational deve ser convertido para Float antes de fazer comparações:
julia> 1//3 == 1/3
false
julia> float(1//3) == 1/3
true
As funções matemáticas aceitam números racionais, mas podem dar um resultado de vírgula flutuante:
julia> sqrt(9//16)
0.75
Uma organização de investigação notou que alguns dos seus investigadores juniores têm vindo a usar métodos menos que ideais nas suas análises. Um desses métodos é converter imediatamente probabilidades discretas em números de vírgula flutuante (ou seja, números reais) antes de fazer mais cálculos.
Os investigadores seniores preferem usar números racionais nos cálculos, que podem proporcionar maior precisão, e gostariam de saber se as más práticas dos investigadores juniores afetaram os resultados dos estudos.
Foram feitos dois tipos de estudos:
Os investigadores seniores estão a pedir-te que escrevas funções que os ajudem a determinar se há erros de arredondamento nas análises por usarem números de vírgula flutuante, e pedem-te que forneças um número racional exato para o resultado, caso haja erros.
A função rationalize(successes, trials) recebe dois arrays, successes e trials.
Para um índice i, successes[i] corresponde ao número de sucessos que ocorreram em trials[i] tentativas.
A função devolve um array de números racionais dos sucessos sobre o número de tentativas, pela mesma ordem que os arrays de entrada.
julia> rationalize([1, 2, 3], [4, 5, 6])
3-element Vector{Rational{Int64}}:
1//4
2//5
1//2
De forma semelhante, a função probabilities(successes, trials) recebe dois arrays, successes e trials.
Devolve um array de números de vírgula flutuante dos sucessos sobre o número de tentativas, pela mesma ordem que os arrays de entrada.
julia> probabilities([1, 2, 3], [4, 5, 6])
3-element Vector{Float64}:
0.25
0.4
0.5
A função checkmean(successes, trials) recebe os dois arrays, successes e trials.
Compara a média das probabilidades reais com a média das probabilidades racionais.
checkmean devolve true
checkmean devolve a probabilidade racional.julia> successes, trials = [9, 4, 7, 8, 6], [22, 22, 11, 17, 12];
julia> checkmean(successes, trials)
true
julia> successes, trials = [6, 5, 9, 8, 9], [21, 19, 13, 25, 22];
julia> checkmean(successes, trials)
1873629//4754750
A função checkprob(successes, trials) recebe os dois arrays, successes e trials.
Compara a probabilidade total obtida com números de vírgula flutuante com a probabilidade total obtida com números racionais.
checkprob devolve true
checkprob devolve a probabilidade racional.julia> successes, trials = [2, 9, 4, 4, 5], [15, 11, 17, 19, 15];
julia> checkprob(successes, trials)
true
julia> successes, trials = [9, 8, 5, 4, 3], [22, 14, 19, 25, 18];
julia> checkprob(sucesses, trials)
12//7315
Inscreve-te no Exercism para aprenderes e dominares Julia com 35 conceitos128 exercícios, e mentoria humana real, tudo grátis.