A Julia é uma linguagem de uso geral que pode ser usada na maioria das tarefas de programação. Na prática, porém, as principais utilizações tendem a ser na engenharia e na ciência. Os cálculos numéricos rápidos, versáteis e sofisticados estão no centro da sua conceção.
Um número inteiro é um número "redondo", sem vírgula decimal.
No conceito Básicos, vimos que é possível atribuir um valor inteiro a uma variável sem especificar o tipo.
Para facilitar a leitura, podem usar-se underscores como separador de algarismos. O compilador ignora-os.
julia> x = 3
3
julia> typeof(x)
Int64
julia> large_number = 1_234_567_890
1234567890
Não é surpresa que os números de vírgula flutuante tenham uma vírgula decimal, e uma parte fracionária depois da vírgula.
julia> f = 3.45
3.45
julia> typeof(f)
Float64
Claro que a notação científica é suportada.
julia> avogadro = 6.02e23
6.02e23
Os valores máximo e mínimo podem surpreender-te:
julia> typemax(Float64)
Inf
julia> typemin(Float64)
-Inf
O infinito é um valor válido!
Como vimos no conceito Básicos, os operadores aritméticos funcionam, na maioria dos casos, como na aritmética normal, aquela que aprendemos em criança.
Repara que a exponenciação usa ^, e não ** (ambos são comuns noutras linguagens).
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 entanto, há alguns pormenores específicos da Julia que vale a pena discutir.
julia> x = 4.2
4.2
julia> 2 * x
8.4
julia> 2x
8.4
julia> 2.4x
10.08
Isso pode ser surpreendente.
É sempre possível usar * como operador infixo, como na maioria das outras linguagens de programação.
No entanto, a Julia foi criada por pessoas que acreditam que o código deve parecer-se o mais possível com equações matemáticas.
Como os nomes de variáveis têm de começar por uma letra, colocar um número (inteiro ou de vírgula flutuante) antes do nome é tratado como multiplicação implícita.
Por exemplo, se quisermos a área da superfície de uma esfera, em vez de 4 * pi * r * r podemos fazer isto:
julia> surface(r) = 4π * r^2
surface (generic function with 1 method)
julia> surface(3)
113.09733552923255
Embora o π seja uma constante incorporada, também é uma letra (grega).
Por isso, o analisador sintático continua a precisar de um * explícito para separar o π do r.
Usar / como operador infixo dá sempre um resultado de vírgula flutuante, mesmo para valores de entrada inteiros.
Para a divisão inteira, há mais opções.
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
A função div() serve para a divisão inteira e trunca o resultado em direção ao zero: para baixo nos números positivos, para cima nos negativos.
Como sinónimo, podemos usar o operador infixo ÷, mais uma vez para o tornar mais matemático.
Se estiveres a usar um editor com suporte para Julia, escreve \div e a seguir prime a tecla <Tab>.
O operador // está para lá do âmbito deste conceito.
Por agora, basta dizer que o resultado de // é um número "racional", aquilo a que a maioria das pessoas chama fração.
Isto pode acontecer automaticamente muitas vezes:
julia> x = 2 + 3.5
5.5
julia> typeof(x)
Float64
Somámos um Int64 a um Float64 e obtivemos um resultado Float64.
Na verdade, o número inteiro foi convertido silenciosamente num Float64 antes de se fazer a adição.
As conversões de vírgula flutuante para inteiro são inevitavelmente mais complicadas. O que queres fazer com o que vem depois da vírgula decimal?
round() converte para o número inteiro mais próximo, com os empates, como 4.5, a arredondar para o número inteiro par mais próximo.floor() arredonda para baixo, ceil() arredonda para cima, trunc() arredonda em direção ao zero.Int32(), dá origem a um InexactError.No entanto, por predefinição, estas funções não devolvem o tipo inteiro que poderias querer. É possível especificar o tipo de resultado pretendido.
julia> round(4.5)
4.0
julia> ceil(Int, 4.3)
5
Também é possível arredondar para um número especificado de algarismos depois da vírgula decimal, através da palavra-chave digits.
julia> round(π, digits=10)
3.1415926536
Certamente que isto dá logo um erro? Na verdade, a situação não é assim tão simples.
A divisão inteira com ÷ ou // dá um erro, como seria de esperar.
A divisão de vírgula flutuante com / segue uma abordagem que se pode considerar de engenharia, em vez da abordagem padrão da informática:
julia> 2 / 0
Inf
julia> 0 / 0
NaN
Como vimos numa secção anterior, o infinito é um número de vírgula flutuante válido na Julia, representado por Inf.
Quando o numerador também é zero, o resultado é matematicamente indefinido.
A Julia trata-o então como "não é um número", representado por NaN.
O teu amigo Chandler planeia visitar países exóticos por todo o mundo. Infelizmente, o Chandler não é bom a matemática. Está bastante preocupado em ser enganado nos câmbios durante a viagem, e quer que lhe faças uma calculadora de moedas. Aqui estão as especificações dele para a aplicação:
Cria a função exchange_money(), que recebe 2 parâmetros:
budget: a quantia de dinheiro que planeias trocar.exchange_rate: a quantidade de moeda nacional equivalente a uma unidade de moeda estrangeira.Esta função deve devolver o valor da moeda trocada.
Nota: se a tua moeda for o USD e quiseres trocar USD por EUR com uma taxa de câmbio de 1.20, então 1.20 USD == 1 EUR.
julia> exchange_money(127.5, 1.2)
106.25
Cria a função get_change(), que recebe 2 parâmetros:
budget: a quantidade de dinheiro antes da troca.exchanging_value: a quantidade de dinheiro que é retirada do orçamento para ser trocada.Esta função deve devolver a quantidade de dinheiro que sobra do orçamento.
julia> get_change(127.5, 120)
7.5
Cria a função get_value_of_bills(), que recebe 2 parâmetros:
denomination: o valor de uma única nota.number_of_bills: o número total de notas.Este posto de câmbio só lida com dinheiro em incrementos específicos. O total que recebes tem de ser divisível pelo valor de uma "nota" ou unidade, o que pode deixar uma fração ou um resto. A tua função deve devolver apenas o valor total das notas (excluindo quantias fracionárias) que o posto devolveria. Infelizmente, o posto fica com o resto/troco como bónus adicional.
julia> get_value_of_bills(5, 128)
640
Cria a função get_number_of_bills(), que recebe amount e denomination.
Esta função deve devolver o número de notas que podes receber dentro do amount indicado. Por outras palavras: quantas notas inteiras cabem na quantia inicial? Lembra-te de que só podes receber notas inteiras, não frações de notas, por isso não te esqueças de dividir em conformidade. Na prática, estás a arredondar para baixo para a nota/denominação inteira mais próxima.
julia> get_number_of_bills(127.5, 5)
25
Cria a função get_leftover_of_bills(), que recebe amount e denomination.
Esta função deve devolver a quantia restante que não pode ser devolvida a partir do teu amount inicial, dada a denominação das notas. É muito importante saber exatamente quanto é que o posto acaba por ficar.
julia> get_leftover_of_bills(127.5, 20)
7.5
Cria a função exchangeable_value(), que recebe budget, exchange_rate, spread e denomination.
O parâmetro spread é a percentagem retirada como comissão de câmbio, escrita como um número inteiro.
Tem de ser convertida em decimal dividindo-a por 100.
Se 1.00 EUR == 1.20 USD e o spread for 10, a taxa de câmbio total será, na verdade: 1.00 EUR == 1.32 USD, porque 10% de 1.20 é 0.12, e esta comissão adicional é somada ao câmbio.
Esta função deve devolver o valor máximo da nova moeda depois de calcular a taxa de câmbio mais o spread. Lembra-te de que a denominação da moeda é um número inteiro e não pode ser subdividida.
Nota: o valor devolvido deve ser do tipo inteiro.
julia> exchangeable_value(127.25, 1.20, 10, 20)
80
julia> exchangeable_value(127.25, 1.20, 10, 5)
95
Inscreve-te no Exercism para aprenderes e dominares Julia com 35 conceitos128 exercícios, e mentoria humana real, tudo grátis.