Los Rational numbers son fracciones con un numerador entero dividido entre un denominador entero.
Por ejemplo, podemos almacenar 2//3 como una fracción exacta en lugar del valor aproximado Float64 0.6666...
La ventaja es que (salvo en el caso extremo de desbordamiento de enteros) un número racional seguirá siendo exacto, lo que evita los errores de redondeo que a menudo son inevitables con los números de coma flotante.
Los números racionales son un tipo numérico bastante sencillo y pretenden funcionar tal y como cabría esperar. Como han sido un tipo estándar en Julia desde las primeras versiones, la mayoría de las funciones los aceptan como entrada igual que los enteros y los números decimales.
Crearlos es tan sencillo como usar // entre dos enteros.
julia> 3//4
3//4
julia> a = 3; b = 4;
julia> a//b
3//4
Los factores comunes se eliminan automáticamente, lo que convierte la fracción a su «mínima expresión»: los enteros más pequeños que representan con exactitud la fracción y con un denominador no negativo.
julia> 5//15
1//3
julia> 5//-15
-1//3
Los arithmetic operators habituales + - * / ^ % funcionan con los racionales, esencialmente igual que con otros tipos numéricos.
Se pueden incluir enteros y otros Rational y dan como resultado un Rational.
Si se incluye un float en la expresión, el resultado es un float, con la consiguiente (posible) pérdida de precisión.
Si se desea un float, basta con usar la función float() para convertir un racional.
Es bastante normal usar números racionales para conservar la precisión a lo largo de un cálculo largo y, después, convertir a un número decimal al 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
En Julia, los números racionales son simplemente números. El compilador suele convertir los tipos según sea necesario.
Sin embargo, ten en cuenta que las comparaciones funcionan para fracciones con una representación decimal finita:
julia> 3//4 == 0.75
true
julia> 3//4 < 0.74
false
Pero, en caso contrario, hay que convertir un Rational a un Float para hacer comparaciones:
julia> 1//3 == 1/3
false
julia> float(1//3) == 1/3
true
Las funciones matemáticas aceptan racionales como entrada, pero pueden dar un resultado de coma flotante:
julia> sqrt(9//16)
0.75
Una organización de investigación ha notado que algunos de sus investigadores júnior han estado utilizando métodos poco óptimos en sus análisis. Uno de estos métodos consiste en convertir de inmediato las probabilidades discretas en números de coma flotante (es decir, números reales) antes de hacer más cálculos.
Los investigadores sénior prefieren usar números racionales en los cálculos, ya que pueden proporcionar una mayor precisión, y les gustaría saber si las malas prácticas de los investigadores júnior han afectado a los resultados de los estudios.
Se realizaron dos tipos de estudios:
Los investigadores sénior te piden que escribas funciones que les ayuden a determinar si hay errores de redondeo en los análisis por usar números de coma flotante, y te piden que proporciones un número racional preciso para el resultado si hay errores.
La función rationalize(successes, trials) recibe dos arrays, successes y trials.
Para un índice i, successes[i] corresponde al número de éxitos que ocurrieron en trials[i] ensayos.
La función devuelve un array de números racionales de los éxitos sobre el número de ensayos, en el mismo orden que los arrays de entrada.
julia> rationalize([1, 2, 3], [4, 5, 6])
3-element Vector{Rational{Int64}}:
1//4
2//5
1//2
Del mismo modo, la función probabilities(successes, trials) recibe dos arrays, successes y trials.
Devuelve un array de números de coma flotante de los éxitos sobre el número de ensayos, en el mismo orden que los arrays de entrada.
julia> probabilities([1, 2, 3], [4, 5, 6])
3-element Vector{Float64}:
0.25
0.4
0.5
La función checkmean(successes, trials) recibe los dos arrays, successes y trials.
Comprueba la media de las probabilidades reales frente a la media de las probabilidades racionales.
checkmean devuelve true
checkmean devuelve la probabilidad 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
La función checkprob(successes, trials) recibe los dos arrays, successes y trials.
Comprueba la probabilidad total de las probabilidades de coma flotante frente a la probabilidad total de las probabilidades racionales.
checkprob devuelve true
checkprob devuelve la probabilidad 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
Regístrate en Exercism para aprender y dominar Julia con 35 conceptos128 ejercicios y mentoría humana real, todo gratis.