1 + 2
3
Objetivo: Ver o interpretador de Julia como uma calculadora poderosa, introduzir a noção de variáveis.
Quem quiser já pode instalar o ambiente de programação, usem esse link. Há também alguns ambientes que permitem o uso da linguagem no seu navegador, sugiro a busca pelas palavras chave Julia Language online
.
Dentro do Julia (após chamar julia na linha de comando), vamos começar com contas com números inteiros:
1 + 2
3
40 * 4
160
Sim, como era de se esperar, podemos em Julia usar os operandos: +
, -
e *
, o resultado será como o esperado. Vejamos a seguir que com a divisão fica um pouco diferente:
= 84
a = 2
b
# As variáveis a e b são do tipo Int64
= a / b
resultado println(resultado)
42.0
Notem que nesse caso, houve uma mudança de tipos, pois 84 e 2 são inteiros e o resultado é um número em ponto flutuante (float), podemos ver isso, pois ao invés de 42, tivemos como resultado 42.0.
Também é possível pedir o resultado inteiro usando o operador div
:
div(84,2)
42
Ou de forma equivalente usando o operador \div
(para conseguir ver o símbolo da divisão é necessário digitar \div
seguido da tecla <tab>
).
Além das contas básicas, também dá para fazer a exponenciação:
2^31
2147483648
Expressões mais complexas também podem ser calculadas:
23 + 2 * 2 + 3 * 4
39
Sim, a precedência de operadores usual também é válida em Julia. Mas, segue a primeira lição de programação: Escreva para humanos, não para máquinas.
23 + (2 * 2) + (3 * 4)
39
Em Julia também podemos fazer operações com números em ponto flutuante:
23.5 * 3.14
73.79
ou
12.5 / 2.0
6.25
Acima temos mais um exemplo de código escrito para pessoas, ao se escrever 2.0 estamos deixando claro que o segundo parâmetro é um número float.
É importante saber que números em ponto flutuante tem precisão limitada, logo não se espante com resultados inesperados como abaixo:
1.2 - 1.0
0.19999999999999996
Erros como esse são bastante raros, tanto que usualmente confiamos plenamente nas contas feitas com computadores e calculadoras. Mas, é bom saber que existem limitações.
2.6 - 0.7 - 1.9
2.220446049250313e-16
ou
0.1 + 0.2
0.30000000000000004
ou ainda
10e15 + 1 - 10e15
0.0
Esses problemas de precisão estão ligados a limitação de como os números são representados no computador. De maneira simplificada, os valores no computador são codificados em palavras, formadas por bits. Nos computadores modernos as palavras tem 64 bits, ou 8 bytes. Logo, uma outra limitação está ligada aos números inteiros muito grandes
2^63
-9223372036854775808
Mas, para um curso introdutório basta saber que existem essas limitações. Como lidar com elas é parte de um curso mais avançado.
É importante notar que o erro acima é um erro silencioso, ou seja quanto estamos usando números inteiros, pode ocorrer que o número a ser representado não caiba no número de bits disponível, o que faz com que ocorra um erro.
Voltando para as contas. Um outro operador interessante é o %
que faz o resto da divisão
4 % 3
1
Até agora vimos como trabalhar com um único valor, ou seja, como se fosse no visor de uma calculadora. Mas, é possível ir além. Ao invés de termos teclas de memória, o computador nos oferece variáveis. Elas são como nomes para valores que queremos guardar e usar mais tarde.
Além das operações básicas também temos as operações matemáticas (funções), como por exemplo o seno, sin em inglês. Para saber como uma função funciona podemos pedir ajuda ao ambiente, usando uma ?
ou o macro @doc
, e em seguida digitando o que queremos saber, como por exemplo em:
@doc sin
A saída desse comando indica a operação que a função realiza e ainda apresenta alguns exemplos:
sin(x)
Compute sine of x, where x is in radians.
See also sind, sinpi, sincos, cis, asin.
Examples
≡≡≡≡≡≡≡≡
julia> round.(sin.(range(0, 2pi, length=9)'), digits=3)
1×9 Matrix{Float64}:
0.0 0.707 1.0 0.707 0.0 -0.707 -1.0 -0.707 -0.0
Ambos os comandos ? sin
@doc sin
possuem a mesma saída.
Notem que nem tudo que foi apresentado faz sentido no momento, mas já dá para entender o uso de uma função como sin. Vejamos agora a raiz quadrada:
@doc sqrt
Nela vemos que é possível calcular a raiz como em:
sqrt(4)
2.0
sqrt(4.0)
2.0
Mas, observamos também na documentação a função big()
, que tem a seguinte ajuda:
@doc BigInt
A função big()
em Julia é usada para criar números inteiros grandes, representados pelo tipo BigInt. Essa função é especialmente útil quando você precisa lidar com números muito grandes que excedem o limite dos tipos inteiros padrão, como Int64 ou Int32.
Com números BigInt, já não há problemas de estouro, como podemos ver abaixo:
big(2) ^ 1002
42860344287450692837937001962400072422456192468221344297750015534814042044997444899727935152627834325103786916702125873007485811427692561743938310298794299215738271099296923941684298420249484567511816728612185899934327765069595070236662175784308251658284785910746168670641719326610497547348822672277504
Podemos ainda carregar funções de outros arquivos em nosso arquivo Julia ou no próprio terminal, para isso basta utilizar o comando include("caminho/do/arquivo.jl")
, Julia lê o arquivo especificado e executa todo o seu conteúdo no contexto atual. Isso significa que todas as funções, variáveis e definições no arquivo tornam-se disponíveis no ambiente onde include
foi chamado.
Como por exemplo no primeiro caso tenho um arquivo chamado funcoes.jl
que possui a função soma:
function ola(nome)
println("Olá", nome)
end
ola (generic function with 1 method)
Podemos incluir essa função em um segundo arquivo utilizando o include("funcoes.jl")
, e utilizar a função definida no arquivo funcoes.jl
include("funcoes.jl")
println(ola("Alfredo"))
Cuja saída deverá ser Olá Alfredo
.
Em Julia também temos o conceito de variáveis, que servem para armazenar os diferentes conteúdos de dados possíveis.
= 7
a 2 + a
9
É importante notar que as variáveis em Julia podem receber novos valores e o tipo da variável depende do que foi atribuído por último.
= 3
a typeof(a)
Int64
= a + 1
a typeof(a)
Int64
Neste próximo exemplo, a variável b é inicializada com um valor de tipo inteiro, contudo, após a operação de multiplicação, seu valor é do tipo ponto flutuante:
= 3
b = b * 0.5
b typeof(b)
Float64
A tipagem dinâmica apresenta diversas vantagens, entre elas a flexibilidade, pois é possível reutilizar variáveis para armazenar diferentes tipos de dados ao longo do tempo; e menos verbosidade, pois não é necessário especificar o tipo de cada variável, o que melhora a legibilidade do código.
Aproveitando o momento, podemos ver que há vários tipos primitivos em Julia, sendo os principais:
typeof(1)
Int64
typeof(1.1)
Float64
typeof("Bom dia")
String
Falando em Strings, elas são definidas por conjuntos de caracteres entre aspas como:
= "Olha que legal"
s1 = "Outra String" s2
"Outra String"
Dá também para fazer operações com strings como concatenação:
= "Tenha um"
s1 = " Bom dia"
s2 = s1 * s2 s3
"Tenha um Bom dia"
Ou potência:
= "Nao vou mais fazer coisas que possam desagradar os meus colegas "
s ^ 10 s
"Nao vou mais fazer coisas que possam desagradar os meus colegas Nao vou mais fazer coisas que possam desagradar os meus colegas Nao vou mais fazer coisas que possam desagradar os meus colegas Nao vou mais fazer coisas que possam desagradar os meus colegas Nao vou mais fa" ⋯ 98 bytes ⋯ "s meus colegas Nao vou mais fazer coisas que possam desagradar os meus colegas Nao vou mais fazer coisas que possam desagradar os meus colegas Nao vou mais fazer coisas que possam desagradar os meus colegas Nao vou mais fazer coisas que possam desagradar os meus colegas "
Ainda sobre variáveis, há umas regras com relação aos seus nomes, tem que começar com uma letra (ou com _
), pode ter dígitos e não pode ser uma palavra reservada. É bom notar que Julia por ser uma linguagem moderna, aceita nomes de caracteres em unicode, por exemplo o Δ (\Delta
):
= 2 Δ
2
Mas, a linguagem vai bem além com caracteres de animais e símbolos:
= 5 # \:cat: <tab>
🐱 = 3 # \:dog: <tab>
🐶 = 20 # \:house: <tab> 🏠
20
Isso não adiciona nada do lado de algoritmos, mas é possível ter variáveis bem bonitinhas. A lista de figuras pode ser encontrada aqui.
Para fazer saídas usam-se dois comandos, print()
e o println()
, sendo que o primeiro não pula linha e o segundo pula.
print("Hello ")
println("World!")
println("Ola, mundo!")
Hello World!
Ola, mundo!
Para evitar que se digitem muitos caracteres, por vezes podemos usar “açucares sintáticos”.
= 1
x = x + 1
x += 1 # forma equivalente a acima, o mesmo vale para os operadores *, - e / x
3
Acima, vimos a forma de se inserir comentários em Julia (sim esses serão ignorados pelo computador).
Exercício: Faça o passo a passo para encontrar as raízes da equação de segundo grau \(x^2 - 5 x + 6\), usando as váriaveis a
, b
, c
, \Delta
, x1
e x2
. Após isso, compare com a solução a seguir:
# Definição dos coeficientes
= 1
a = -5
b = 6
c
# Cálculo do discriminante
= b^2 - 4 * a * c
delta
# Cálculo das raízes
if delta >= 0
= (-b + sqrt(delta)) / (2 * a)
x1 = (-b - sqrt(delta)) / (2 * a)
x2 println("As raízes são: x1 = $x1 e x2 = $x2")
else
println("A equação não possui raízes reais.")
end
As raízes são: x1 = 3.0 e x2 = 2.0