Julia es un lenguaje de propósito general que puede usarse para la mayoría de las tareas de programación. En la práctica, sin embargo, sus principales casos de uso suelen darse en la ingeniería y la ciencia. Los cálculos numéricos rápidos, versátiles y sofisticados son fundamentales en su diseño.
Un número entero es un número «redondo», sin parte decimal.
En el concepto Fundamentos vimos que se puede asignar un valor entero a una variable sin especificar un tipo.
Por legibilidad, se pueden usar guiones bajos como separador de dígitos. El compilador los ignora.
julia> x = 3
3
julia> typeof(x)
Int64
julia> large_number = 1_234_567_890
1234567890
No sorprenderá que los números de coma flotante tengan una coma decimal y una parte fraccionaria después de la coma.
julia> f = 3.45
3.45
julia> typeof(f)
Float64
Por supuesto, se admite la notación científica.
julia> avogadro = 6.02e23
6.02e23
Los valores máximo y mínimo pueden sorprenderte:
julia> typemax(Float64)
Inf
julia> typemin(Float64)
-Inf
¡El infinito es un valor válido!
Como vimos en el concepto Fundamentos, los operadores aritméticos funcionan en su mayor parte igual que la aritmética estándar que se enseña a los niños.
Ten en cuenta que la exponenciación usa ^, no ** (ambos son habituales en otros lenguajes).
2 + 3 # 5 (addition)
2 - 3 # -1 (subtraction)
2 * 3 # 6 (multiplication)
8 / 2 # 4.0 (division)
8 % 3 # 2 (remainder)
2 ^ 3 # 8 (exponentiation)
No obstante, merece la pena comentar algunos detalles específicos de Julia.
julia> x = 4.2
4.2
julia> 2 * x
8.4
julia> 2x
8.4
julia> 2.4x
10.08
Eso puede resultar sorprendente.
Siempre es posible usar * como operador infijo, como en la mayoría de los demás lenguajes.
Sin embargo, Julia está diseñada por personas que creen que el código debería parecerse lo máximo posible a las ecuaciones matemáticas.
Como los nombres de las variables deben empezar por una letra, anteponer un número (entero o de coma flotante) al nombre se interpreta como una multiplicación implícita.
Por ejemplo, si queremos el área de la superficie de una esfera, en lugar de 4 * pi * r * r podríamos hacer esto:
julia> surface(r) = 4π * r^2
surface (generic function with 1 method)
julia> surface(3)
113.09733552923255
Aunque π es una constante integrada, también es una letra (griega).
Por eso el analizador sintáctico sigue necesitando un * explícito para separar π de r.
Usar / como operador infijo siempre da como resultado un número de coma flotante, incluso con entradas enteras.
Para la división entera hay más opciones.
julia> 10 / 3 # floating-point division
3.3333333333333335
julia> div(10, 3) # integer division
3
julia> 10 ÷ 3 # synonym for div()
3
julia> 10 // 3 # rational number (fraction)
10//3
La función div() sirve para la división entera, y su resultado se trunca hacia cero: hacia abajo para los números positivos y hacia arriba para los negativos.
Como sinónimo, podemos usar el operador infijo ÷, de nuevo con la intención de que parezca más matemático.
Si usas un editor que entienda Julia, escribe \div y luego pulsa la tecla <Tab>.
El operador // queda fuera del alcance de este concepto.
Por ahora, basta con decir que el resultado de // es un número «racional», que la mayoría de la gente llama fracción.
Esto a menudo ocurre de forma automática:
julia> x = 2 + 3.5
5.5
julia> typeof(x)
Float64
Hemos sumado un Int64 a un Float64 y el resultado ha sido un Float64.
De hecho, el entero se convirtió de forma silenciosa en un Float64 antes de hacer la suma.
Las conversiones de coma flotante a entero son inevitablemente más complicadas. ¿Qué quieres hacer con lo que haya después de la coma decimal?
round() convierte al número entero más próximo y, en los empates, como 4,5, redondea al número entero par más próximo.floor() redondea hacia abajo, ceil() hacia arriba y trunc() hacia cero.Int32(), fallará con un InexactError.No obstante, de forma predeterminada estas funciones no devuelven el tipo entero que quizá esperabas. Puedes especificar el tipo de salida que quieres.
julia> round(4.5)
4.0
julia> ceil(Int, 4.3)
5
También es posible redondear a un número concreto de dígitos después de la coma decimal con la palabra clave digits.
julia> round(π, digits=10)
3.1415926536
¿Seguro que esto simplemente lanza un error? En realidad, la situación no es tan sencilla.
La división entera con ÷ o // da lugar a un error, como cabría esperar.
La división de coma flotante con / adopta lo que podría considerarse un enfoque de ingeniería, en lugar del enfoque habitual de las ciencias de la computación:
julia> 2 / 0
Inf
julia> 0 / 0
NaN
Como vimos en una sección anterior, el infinito es un número de coma flotante válido en Julia y se representa con Inf.
Cuando el numerador también es cero, el resultado es matemáticamente indefinido.
En ese caso Julia lo trata como «no es un número», representado por NaN.
Tu amigo Chandler planea visitar países exóticos de todo el mundo. Por desgracia, Chandler no es bueno con las matemáticas. Está bastante preocupado por que le estafen en las casas de cambio durante su viaje, y quiere que le hagas una calculadora de divisas. Estas son sus especificaciones para la aplicación:
Crea la función exchange_money(), que toma 2 parámetros:
budget: la cantidad de dinero que planeas cambiar.exchange_rate: la cantidad de moneda nacional equivalente a una unidad de moneda extranjera.Esta función debe devolver el valor de la moneda cambiada.
Nota: Si tu moneda es el USD y quieres cambiar USD por EUR con un tipo de cambio de 1.20, entonces 1.20 USD == 1 EUR.
julia> exchange_money(127.5, 1.2)
106.25
Crea la función get_change(), que toma 2 parámetros:
budget: cantidad de dinero antes del cambio.exchanging_value: cantidad de dinero que se toma del presupuesto para cambiarla.Esta función debe devolver la cantidad de dinero que queda del presupuesto.
julia> get_change(127.5, 120)
7.5
Crea la función get_value_of_bills(), que toma 2 parámetros:
denomination: el valor de un solo billete.number_of_bills: el número total de billetes.Esta oficina de cambio solo opera con efectivo de determinados incrementos. El total que recibes debe ser divisible por el valor de un «billete» o unidad, lo que puede dejar una fracción o un residuo. Tu función debe devolver solo el valor total de los billetes (excluyendo las cantidades fraccionarias) que la oficina te devolvería. Por desgracia, la oficina se queda con el residuo/cambio como bonificación adicional.
julia> get_value_of_bills(5, 128)
640
Crea la función get_number_of_bills(), que toma amount y denomination.
Esta función debe devolver el número de billetes que puedes recibir dentro del amount dado. En otras palabras: ¿cuántos billetes completos caben en la cantidad inicial? Recuerda que solo puedes recibir billetes completos, no fracciones de billetes, así que acuérdate de dividir en consecuencia. En efecto, estás redondeando hacia abajo hasta el billete/denominación entero más cercano.
julia> get_number_of_bills(127.5, 5)
25
Crea la función get_leftover_of_bills(), que toma amount y denomination.
Esta función debe devolver el importe sobrante que no se puede devolver de tu amount inicial dada la denominación de los billetes. Es muy importante saber exactamente cuánto se queda la oficina.
julia> get_leftover_of_bills(127.5, 20)
7.5
Crea la función exchangeable_value(), que toma budget, exchange_rate, spread y denomination.
El parámetro spread es el porcentaje que se aplica como comisión de cambio, escrito como un número entero.
Hay que convertirlo a decimal dividiéndolo por 100.
Si 1.00 EUR == 1.20 USD y el spread es 10, el tipo de cambio total será en realidad: 1.00 EUR == 1.32 USD, porque el 10 % de 1,20 es 0,12, y esta comisión adicional se suma al cambio.
Esta función debe devolver el valor máximo de la nueva moneda tras calcular el tipo de cambio más el spread. Recuerda que la denominación de la moneda es un número entero y no se puede subdividir.
Nota: El valor devuelto debe ser de tipo entero.
julia> exchangeable_value(127.25, 1.20, 10, 20)
80
julia> exchangeable_value(127.25, 1.20, 10, 5)
95
Regístrate en Exercism para aprender y dominar Julia con 35 conceptos128 ejercicios y mentoría humana real, todo gratis.