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 estar 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 entero es un número «exacto», sin punto decimal.
En el concepto Básicos, vimos que se puede asignar un valor entero a una variable sin especificar un tipo.
Para que sea más fácil de leer, 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 punto flotante tengan un punto decimal y una parte fraccionaria después del punto.
julia> f = 3.45
3.45
julia> typeof(f)
Float64
Por supuesto, la notación científica es compatible.
julia> avogadro = 6.02e23
6.02e23
Los valores máximo y mínimo pueden sorprender:
julia> typemax(Float64)
Inf
julia> typemin(Float64)
-Inf
¡El infinito es un valor válido!
Como se explicó en el concepto Básicos, los operadores aritméticos funcionan en su mayoría 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 comunes 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)
Sin embargo, vale 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 sorprender.
Siempre es posible usar * como operador infijo, como en la mayoría de los otros lenguajes de programación.
Sin embargo, Julia fue diseñado por personas que creen que el código debería parecerse lo más posible a las ecuaciones matemáticas.
Como los nombres de las variables deben empezar con una letra, anteponer un número (entero o de punto flotante) al nombre se trata 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 incorporada, también es una letra (griega).
Por eso el analizador sintáctico todavía necesita un * explícito para separar π de r.
Usar / como operador infijo siempre da un resultado de punto flotante, incluso con números enteros.
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, con el resultado truncado hacia cero: hacia abajo para los números positivos, hacia arriba para los negativos.
Como sinónimo, podemos usar el operador infijo ÷, de nuevo con la intención de que se vea más matemático.
Si usas un editor que entiende Julia, escríbelo como \div y luego presiona la tecla <Tab>.
El operador // está más allá 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 puede ocurrir automáticamente:
julia> x = 2 + 3.5
5.5
julia> typeof(x)
Float64
Sumamos un Int64 a un Float64 y obtuvimos un resultado Float64.
De hecho, el entero se convirtió silenciosamente en un Float64 antes de hacer la suma.
Las conversiones de punto flotante a entero son inevitablemente más complicadas. ¿Qué quieres hacer con lo que queda después del punto decimal?
round() convierte al número entero más cercano; en los empates, como 4.5, redondea al número entero par más cercano.floor() redondea hacia abajo, ceil() hacia arriba y trunc() hacia cero.Int32(), fallará con un InexactError.Sin embargo, por defecto estas funciones no devuelven el tipo entero que quizá querías. Se puede especificar el tipo de salida deseado.
julia> round(4.5)
4.0
julia> ceil(Int, 4.3)
5
También es posible redondear a un número específico de dígitos después del punto decimal con la palabra clave digits.
julia> round(π, digits=10)
3.1415926536
¿Acaso esto no lanza simplemente un error? En realidad, la situación no es tan simple.
La división entera con ÷ o // dará como resultado un error, como era de esperar.
La división de punto flotante con / adopta lo que podría considerarse un enfoque de ingeniería, en lugar del enfoque estándar de las ciencias de la computación:
julia> 2 / 0
Inf
julia> 0 / 0
NaN
Como se explicó en una sección anterior, el infinito es un número de punto flotante válido en Julia, representado por Inf.
Cuando el numerador también es cero, el resultado es matemáticamente indefinido.
Entonces 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. Lamentablemente, Chandler no es bueno para las matemáticas. Está bastante preocupado por que lo estafen en los cambios de divisas 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 recibe 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 ya cambiada.
Nota: si tu moneda es USD y quieres cambiar USD por EUR con una tasa 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 recibe 2 parámetros:
budget: la cantidad de dinero antes del cambio.exchanging_value: la 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 recibe 2 parámetros:
denomination: el valor de un solo billete.number_of_bills: el número total de billetes.Esta casa de cambio solo opera con efectivo en ciertos incrementos. El total que recibes debe ser divisible entre 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 (sin incluir las fracciones) que la casa de cambio te daría. Lamentablemente, la casa de cambio se queda con el residuo o cambio como un bono extra.
julia> get_value_of_bills(5, 128)
640
Crea la función get_number_of_bills(), que recibe amount y denomination.
Esta función debe devolver la cantidad de billetes que puedes recibir dentro del monto indicado. En otras palabras: ¿cuántos billetes completos caben en el monto inicial? Recuerda que solo puedes recibir billetes completos, no fracciones de billetes, así que divide en consecuencia. En la práctica, estás redondeando hacia abajo al billete o denominación completa más cercana.
julia> get_number_of_bills(127.5, 5)
25
Crea la función get_leftover_of_bills(), que recibe amount y denomination.
Esta función debe devolver el monto sobrante que no se puede devolver a partir del monto inicial, dada la denominación de los billetes. Es muy importante saber exactamente cuánto se queda la casa de cambio.
julia> get_leftover_of_bills(127.5, 20)
7.5
Crea la función exchangeable_value(), que recibe budget, exchange_rate, spread y denomination.
El parámetro spread es el porcentaje que se cobra como comisión por el cambio, escrito como un número entero.
Se debe convertir a decimal dividiéndolo entre 100.
Si 1.00 EUR == 1.20 USD y el spread es 10, la tasa de cambio total en realidad será 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 después de calcular la tasa 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.