Rational numbers são frações com um numerador inteiro dividido por um denominador inteiro.
Por exemplo, podemos armazenar 2//3 como uma fração exata em vez do valor aproximado Float64 0.6666...
A vantagem é que (exceto no caso extremo de estouro de inteiro) um número racional permanece exato, evitando os erros de arredondamento que muitas vezes são inevitáveis com números de ponto flutuante.
Números racionais são um tipo numérico bem simples e funcionam praticamente como você espera. Como são um tipo padrão do Julia desde as primeiras versões, a maioria das funções os aceita como entrada do mesmo jeito que aceita inteiros e números de ponto flutuante.
Criar um número racional é tão simples quanto 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 para a sua "forma irredutível": os menores inteiros que representam a fração exatamente, com um denominador não negativo.
julia> 5//15
1//3
julia> 5//-15
-1//3
Os arithmetic operators usuais, + - * / ^ %, funcionam com racionais, basicamente do mesmo jeito que com outros tipos numéricos.
Inteiros e outros Rationals podem ser incluídos e dão um resultado Rational.
Incluir um float na expressão resulta em uma saída float, com uma consequente (possível) perda de precisão.
Se você quiser um float, basta usar a função float() para converter um número racional.
É bem comum usar números racionais para preservar a precisão ao longo de um cálculo longo e depois converter para um número de ponto flutuante no final.
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
No Julia, números racionais são apenas números. O compilador geralmente converte os tipos conforme necessário.
No entanto, cuidado: 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 isso, um Rational deve ser convertido para um Float para fazer comparações:
julia> 1//3 == 1/3
false
julia> float(1//3) == 1/3
true
Funções matemáticas aceitam racionais como entrada, mas podem dar um resultado de ponto flutuante:
julia> sqrt(9//16)
0.75
Uma organização de pesquisa percebeu que alguns de seus pesquisadores júnior vêm usando métodos pouco ideais em suas análises. Um desses métodos é converter imediatamente probabilidades discretas em números de ponto flutuante (ou seja, números reais) antes de fazer mais cálculos.
Os pesquisadores sênior preferem usar números racionais nos cálculos, o que pode oferecer maior precisão, e gostariam de saber se as práticas ruins dos pesquisadores júnior afetaram os resultados dos estudos.
Foram feitos dois tipos de estudo:
Os pesquisadores sênior estão pedindo que você escreva funções que os ajudem a determinar se há erros de arredondamento nas análises por usar números de ponto flutuante, e pedem que você forneça um número racional preciso 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 retorna um array de números racionais das razões entre os sucessos e o número de tentativas, na mesma ordem dos 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.
Ela retorna um array de números de ponto flutuante das razões entre os sucessos e o número de tentativas, na mesma ordem dos 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.
Ela compara a média das probabilidades reais com a média das probabilidades racionais.
checkmean retorna true
checkmean retorna 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.
Ela compara a probabilidade total das probabilidades em ponto flutuante com a probabilidade total das probabilidades racionais.
checkprob retorna true
checkprob retorna 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
Crie sua conta no Exercism para aprender e dominar Julia com 35 conceitos128 exercícios e mentoria humana de verdade, tudo de graça.