Prévia do material em texto
Aritmética computacional e zeros de
funções não lineares em Python
Você vai entender os fundamentos da aritmética computacional, reconhecer os erros que surgem nesse
contexto e aprender métodos para encontrar raízes de funções não lineares, aspectos essenciais para
quem utiliza programação em problemas de modelagem matemática.
Prof. Francisco Roberto da Rocha Gomes
1. Itens iniciais
Preparação
Para compreender os conceitos abordados, é necessário conhecimento básico de operações matemática e
linguagem Python.
Objetivos
Reconhecer os conceitos básicos da linguagem Python.
Aplicar os recursos do Python na aritmética computacional distinguindo os tipos de erros
computacionais.
Calcular zeros de funções não lineares utilizando Python.
Introdução
Olá! Para começar, assista a este vídeo e descubra como usar Python na modelagem matemática. Entenda os
conceitos básicos da linguagem, veja como os computadores representam números e conheça os erros que
podem surgir. Explore métodos numéricos, como bisseção e Newton-Raphson, implemente soluções em
Python e analise a precisão dos resultados.
Conteúdo interativo
Acesse a versão digital para assistir ao vídeo.
•
•
•
1. Recursos do Python: conceitos básicos de programação e bibliotecas
Introdução ao Python: sintaxe básica, variáveis e
operadores
Confira neste vídeo como começar a programar em Python. Aprenda a criar e usar variáveis, aplicar
operadores aritméticos e relacionais, manipular strings com indexação e fatiamento, além de explorar
expressões booleanas e operadores lógicos.
Conteúdo interativo
Acesse a versão digital para assistir ao vídeo.
A linguagem Python é uma ferramenta poderosa e acessível para introduzir conceitos da programação e
aplicá-los na resolução de problemas matemáticos. Nosso foco neste conteúdo estará na sintaxe básica da
linguagem, no uso de variáveis e na aplicação de operadores, elementos essenciais para estruturar cálculos e
expressões lógicas. Para melhor compreensão, faremos uso de alguns tipos de dados, como strings, inteiros e
números de ponto flutuante. Vamos lá!
Variáveis
Podemos pensar em uma variável como uma "caixa" na memória do computador, identificada por um nome,
em que guardamos um valor. Em Python, usamos o operador de atribuição (=) para associar um valor a um
nome de variável. Por exemplo, cria uma variável chamada e armazena o valor 5 nela. Sempre que o
Python encontrar o nome x posteriormente no código, ele utilizará o valor armazenado (neste caso, 5).
Atenção
O sinal (=) tem significados diferentes em programação (atribuição) e em matemática (igualdade). Na
matemática, é uma equação a ser resolvida, resultando em . Em programação, significaria: pegue o valor
atual de , subtraia-o de 4 e armazene o resultado de volta na variável , o que é comum em processos
iterativos.
Note que usamos x para representar uma variável. Mas suponha que, após 100 linhas de código, você deseje
usar a mesma variável novamente. Você saberia qual o significado dessa variável? É uma boa prática de
programação utilizar nomes de variáveis descritivos, que indiquem claramente o propósito ou o conteúdo que
armazenam. Vejam este exemplo:
python
1. # atribuição de variáveis
2. temperatura = 39
3. media_alunos = 7.5
4. resultado_final = media_turma # Atribuindo a média final ao resultado final.
Observando o trecho de código, note que, na variável temperatura, foi atribuído um número inteiro. Já na
variável media_alunos, foi atribuído um valor do tipo float (número com casas decimais). Usamos o caractere
underline (_) para unir palavras e tornar o nome mais legível. Por fim, a variável resultado_final recebe como
valor outra variável, o que também é comum em expressões mais complexas.
Isso facilita a leitura, a manutenção e o entendimento do código, especialmente em projetos maiores ou
quando o código precisa ser revisado por outras pessoas ou por você mesmo no futuro.
Com isso, ao escrever programas, é importante documentá-los para manutenções futura ou para que outras
pessoas possam entendê-los. Em Python, utilizamos o caractere cerquilha (#) para indicar comentários como
pode ser visto na linha 1 e linha 4 do exemplo apresentado. Tudo que vier após o # em uma linha é ignorado
pelo interpretador, servindo apenas como anotação para o programador.
Operadores
Python suporta diretamente as operações aritméticas básicas que usamos na matemática:
+: Adição.
-: Subtração.
*: Multiplicação.
/: Divisão (resulta sempre em um número de ponto flutuante, ex:
**: Exponenciação (potência).
%: Módulo (resto da divisão inteira).
//: Divisão inteira (descarta a parte fracionária).
Além de conhecer os operadores, é importante entender a precedência nas operações. Assim como na
matemática, algumas operações são realizadas antes de outras. Por exemplo, a exponenciação (**) tem maior
precedência que a multiplicação que, por sua vez, tem maior precedência que a adição e subtração.
Parênteses podem ser usados para alterar a ordem padrão de avaliação.
A seguir, veja exemplos simples no uso de operadores e sua relação de precedência na linguagem Python.
python
1. # Exemplos de Operadores Aritméticos
2. soma = 5 + 3 # resultado: 8
3. diferenca = 10 - 4 # resultado: 6
4. produto = 7 * 6 # resultado: 42
5. divisao = 10 / 4 # resultado: 2.5
6. potencia = 2 ** 3 # resultado: 8 (2 elevado a 3)
7. resto = 10 % 3 # resultado: 1 (10 dividido por 3 dá 3, resto 1)
8. div_inteira = 10 // 3 # resultado: 3
9. # Exemplo de precedência
10. resultado = 2 + 3 * 4 # resultado: 14 (multiplicação ocorre antes da adição)
11. resultado2 = (2 + 3) * 4 # resultado: 20 (parênteses mudam a ordem da operação)
•
•
•
•
•
•
•
Também podemos usar variáveis em operações. Por exemplo, na linha 4 do código é feito o cálculo do
montante de uma operação financeira. Neste exemplo, usamos a fórmula dos juros compostos:
Acompanhe adiante!
python
1. capital = 1000
2. t = 10
3. i = 0.01
4. montante = capital*(1+i)**t
5. print(f"O valor acumulado será de: {montante:.2f}.")
Na linha 5, utilizamos a função print() para exibir o resultado formatado. O trecho (:.2f) dentro da f-string
indica que o número deve ser exibido com duas casas decimais, o que é útil para apresentar valores
monetários de forma mais clara e padronizada. Nesse exemplo, a saída é o valor acumulado que será de:
1104.62.
Atenção
Na linguagem Python, os números decimais utilizam ponto (.) em vez de vírgula (,).
String
Representa sequências de caracteres (texto). Em Python, ela pode ser definida usando aspas simples (') ou
duplas ("). Existem caracteres especiais que podem ser usados para realizar quebras de linha, tabulações ou
aspas dentro de uma string. Por exemplo: In cria uma nova linha, \t cria uma tabulação e \b representa um
backspace.
No exemplo a seguir, mostramos o efeito do uso do “\n” na impressão em duas linhas.
python
1. texto1 = 'Olá, Python!'
2. texto2 = "Bom dia!"
3. print(f"{texto1}\n{texto2}") # Imprime em duas linhas
Como saída teremos:
python
Olá, Python!
Bom dia!
Podemos acessar caracteres individuais de uma string usando indexação. O primeiro caractere tem índice 0, o
segundo índice 1, e assim por diante. Python também suporta indexação negativa, em que -1 se refere ao
último caractere, -2 ao penúltimo etc. Veja!
python
1. palavra = "Python"
2. print(palavra[0]) # Saída: P (primeiro caractere)
3. print(palavra[2]) # Saída: t
4. print(palavra[-1]) # Saída: n (último caractere)
5. print(palavra[-2]) # Saída: o
Também podemos extrair subsequências, fatias ou slices de uma string usando a notação string[inicio:fim].
Isso retorna a parte da string começando no índice início (inclusivo) até o índice fim (exclusivo). Se início for
omitido, começa do início. Se fim for omitido, vai até o final. Veja o exemplo a seguir.
python
1. palavra = "Python"
2. print(palavra[0:3]) # Saída: Pyt (índices 0, 1, 2)
3. print(palavra[3:5])de importar qualquer método usando "import". No entanto, para algumas
funções como cos(x) é preciso usar "import math". Teste essas alterações no código. Inclua "import math"
antes da linha 1 e na linha 27, troque a função existente pela função da seguinte forma:
math.cos . Ajuste também o intervalo inicial para -1 e 1 respectivamente (linhas 30 e 31).
Atividade 3
Considere a função . Deseja-se encontrar uma raiz da equação . Usando o método
da posição falsa e o intervalo , qual é o valor da segunda aproximação da raiz usando uma precisão de
quatro casas decimais?
A 0,8750
B 1,0000
C 0,4659
D 1,0385
E 0,2857
A alternativa C está correta.
Vamos lá!
Aplicando a verificação . O novo intervalo é . Então a e b .
Com isso:
Método de Newton-Raphson
Conheça neste vídeo o método de Newton-Raphson para encontrar raízes. A partir de um valor inicial, ele usa
a tangente da função (via derivada) para gerar aproximações sucessivas, com convergência rápida em
condições favoráveis.
Conteúdo interativo
Acesse a versão digital para assistir ao vídeo.
O método de Newton-Raphson é uma técnica numérica iterativa muito importante para encontrar raízes de
funções reais. Diferente da bisseção e da Regula Falsi, que utilizam apenas os valores da função nos extremos
de um intervalo, o método de Newton-Raphson usa taxa de variação, ou seja, a derivada. A partir de um valor
inicial, ele utiliza o comportamento da função para determinar um valor mais próximo da raiz. Quando bem
aplicado, oferece convergência rápida, mas exige que a função seja diferenciável e o ponto inicial esteja
razoavelmente próximo da solução.
Tanto no método da bisseção como no método da falsa posição compartilham a mesma condição inicial.
Sendo a função contínua em um intervalo e , então no intervalo existe pelo
menos uma raiz tal que . Já o método de Newton-Raphson usa um "chute" inicial. A partir desse
valor inicial, o método utiliza aproximações sucessivas com intuito de aproximar da raiz.
Vamos compreender melhor esse procedimento analisando a imagem a seguir com detalhes.
Conteúdo interativo
Acesse a versão digital para ver mais detalhes da imagem
abaixo.
Representação gráfica do método de Newton-Raphson.
Na imagem, seja a função representada em azul, tomamos um valor inicial sobre o eixo x que
produz . Pelo ponto traçamos uma reta tangente que intercepta o eixo x em . Observe
que produz agora . Repetindo o processo anterior, pelo ponto traçamos uma nova
reta tangente que intercepta o eixo x em . Continuando esse procedimento, teremos e assim
mais próximo da raiz procurada estaremos. Ou seja, no n-ésimo passo teremos . Logo, buscamos
os valores sobre o eixo que pertencem à reta tangente a cada passo.
Então, pela equação da reta:
Seja o ponto . Queremos obter a próxima aproximação . Observe que em que
pertence a reta tangente que passa por ( ), . Substituindo na equação da reta, teremos:
Note que ainda não substituímos a variável , mas sabemos que ela representa o coeficiente angular da reta,
no caso, de uma reta tangente à função.
Matematicamente, esse coeficiente angular (ângulo de inclinação da reta) é obtido pela derivada da função no
ponto de tangência. Nesse caso, . Agora, a equação da reta passa ser:
Fazendo uma manipulação algébrica . Dividindo ambos os lados da
equação por chegamos a:
Procedendo da mesma forma:
Então, cada aproximação depende da aproximação anterior. Em termos gerais, para obter dependemos
. Com isso, o método pode ser generalizado na forma:
A grande vantagem desse método é que, se o "chute" inicial for bom, ele converge muito rapidamente para a
raiz. A desvantagem é que precisamos calcular a derivada e ele pode falhar se o "chute" inicial for ruim ou se a
derivada for zero perto da raiz. Veja agora um exemplo prático do método calculando o valor aproximado da
.
A função que usaremos é e . Cada aproximação será obtida por:
Seja nosso "chute" inicial . Com isso, e . Então:
Sendo:
A seguir, veja o método Newton-Raphson desenvolvido na linguagem Python. Como exemplo, calculamos uma
das raízes da função , que tem como derivada .
python
1. def newton_raphson(f, df, x0, tol ):
2.
3. erro_rel = 1
4. while erro_rel >=tol:
5.
6. fx = f(x0)
7. dfx = df(x0)
8.
9. if dfx == 0:
10. print("Derivada nula. Método falhou.")
11. return None
12.
13. x1 = x0 - fx / dfx
14.
15. # Erro relativo
16. erro_rel = abs((x1 - x0) / x1)
17.
18. if erro_relPython: sintaxe básica, variáveis e operadores
Conteúdo interativo
Variáveis
Atenção
Operadores
Atenção
String
Expressões booleanas
Atividade 1
Estruturas de dados sequenciais: tuplas e listas
Conteúdo interativo
Tupla
Lista
Uso de operadores em sequências
Atividade 2
Modularidade e controle de fluxo em Python
Conteúdo interativo
Funções
Estruturas condicionais (if, elif, else)
Laços (for) e a função range
Gráficos
Conteúdo interativo
Atividade 3
2. Representação numérica de erros na aritmética em pontos flutuantes
Representação de números inteiros
Conteúdo interativo
Representação dos números inteiros positivos
Exemplo
Atividade 1
Conversão entre os sistemas de numeração
Conteúdo interativo
Mudança da base b para a base decimal 10
Mudança da base 10 para a base b
Conteúdo interativo
Conteúdo interativo
Conteúdo interativo
Conteúdo interativo
Bits e representação dos números inteiros negativos
Atenção
Atividade 2
Representação dos números reais
Conteúdo interativo
Mudança de base 10 para a base b
Mudança da base b para a base 10
Notação científica dos números reais
Representação em ponto flutuante
Mantissa
Expoente
Exemplo
Atividade 3
Erros na aritmética em pontos flutuantes
Conteúdo interativo
Erros de representação
Arredondamento por truncamento
Exemplo
Arredondamento por aproximação
Erro para o valor truncado
Erro para valor arredondado
Atenção
Erro absoluto e erro relativo
Exemplo
Atividade 4
Erros nas operações aritméticas
Conteúdo interativo
Atenção
Multiplicação
Atenção
Divisão
Cancelamento catastrófico
Erro absoluto
Erro relativo
Atenção
Atividade 5
3. Raízes de funções não lineares
Convergência em processos numéricos
Conteúdo interativo
Atividade 1
Método da bisseção
Conteúdo interativo
Conteúdo interativo
Conteúdo interativo
Atividade 2
Método da falsa posição
Conteúdo interativo
Conteúdo interativo
Atividade 3
Método de Newton-Raphson
Conteúdo interativo
Conteúdo interativo
Atividade 4
4. Conclusão
Considerações finais
O que você aprendeu neste conteúdo?
Podcast
Conteúdo interativo
Explore +
Referências# Saída: ho (índices 3, 4)
4. print(palavra[:4]) # Saída: Ling (do início até índice 3)
5. print(palavra[4:]) # Saída: on (do índice 4 até o final)
Expressões booleanas
O resultado dessas expressões é sempre verdadeiro (True) ou falso (False). Elas servem para comparações e
tomadas de decisão. Os operadores relacionais incluem:
: Maior que
=: Maior ou igual a
==: Igual a (atenção: dois sinais de igual para comparação!)
!=: Diferente de
O exemplo a seguir mostra o resultado de cada comparação. Em Python, os tipos de dados são diferenciados,
como nas linhas 8 e 9: o número inteiro 5 é diferente da string '5'.
•
•
•
•
•
•
python
1. # Exemplos de Operadores Relacionais
2. a = 5
3. b = 3.0
4. c = '5'
5. print(a > b) # Saída: True
6. print(a == 5) # Saída: True
7. print(a == b) # Saída: False
8. print(a == c) # Saída: False (inteiro 5 é diferente da string '5')
9. print(a != b) # Saída: True
10.
Podemos combinar expressőes booleanas usando os operadores lógicos and (E lógico) e or (OU lógico). A and
B só é True se ambos A e B forem True. A or B é True se pelo menos um deles (A ou B ou ambos) for True.
Confira o exemplo a seguir.
python
1. # Exemplos de Operadores Lógicos
2. x = 10
3. y = -1
4. print((x > 0) and (y 2)
Com base nele, qual será a saída (output) impressa na tela quando esse código for executado?
A False
B True.
C 2.5.
D Resultado.
E O código gerará um erro de tipo (TypeError).
A alternativa B está correta.
São definidas as variáveis . A expressão booleana , corresponde a divisão de 10
/ 4.0. A divisão resulta em ponto flutuante, então . E . Essa comparação é verdadeira
(True).
Estruturas de dados sequenciais: tuplas e listas
Assista a este vídeo e aprenda a trabalhar com tuplas e listas em Python. Veja como criar, acessar, fatiar,
concatenar e repetir essas estruturas. Entenda a diferença entre a imutabilidade das tuplas e a flexibilidade
das listas, além de descobrir como adicionar e inserir novos itens.
Conteúdo interativo
Acesse a versão digital para assistir ao vídeo.
Listas e tuplas são estruturas de dados em Python utilizadas para armazenar coleções ordenadas de itens.
Compreender suas propriedades é necessário para a construção de programas eficientes e bem organizados.
Vamos agora aprender a criar, acessar e manipular listas e tuplas, observando suas diferenças e aplicações.
Tupla
É uma sequência de objetos separados por vírgulas, geralmente colocados entre parênteses (). Os objetos
dentro de uma tupla podem ser de tipos diferentes. As tuplas são imutáveis, ou seja, não podem ter seus
elementos alterados, adicionados ou removidos. Se a tupla contiver apenas um objeto, uma virgula final é
necessária para diferenciá-la de uma simples expressão entre parênteses, por exemplo, ,
python
1. # Criando tuplas
2. dados_pessoais = ('Gomes', 'Roberto', 31, 10, 1973) # Nome, Sobrenome, dia, mês, ano
3. ponto = (10.5, -3.2) # Coordenadas x, y
4. tupla_unica = (42,) # Tupla com um único elemento
5. tupla_vazia = () # Tupla vazia
6.
Assim como strings, tuplas suportam indexação e fatiamento para acessar seus elementos. No exemplo a
seguir estamos acessando as informações armazenadas na tupla dados_pessoais.
python
1. print(dados_pessoais[0]) # Saída: Gomes (acessa o primeiro elemento)
2. print(dados_pessoais[-1]) # Saída: 1973 (acessa o último elemento)
3. print(dados_pessoais[2:4]) # Saída: (31, 10) (fatiamento do índice 2 até 3)
Por serem imutáveis, tentar modificar um elemento de uma tupla gerará um erro. Por exemplo, se quiséssemos
alterar o nome “Gomes” para “Silva” teríamos que usar o comando:
python
dados_pessoais[0] = 'Silva'
Com isso, geraria um erro:
python
TypeError: 'tuple' object does not support item assignment
Lista
É semelhante a uma tupla por ser uma sequência ordenada de objetos, mas com a diferença de ser mutável.
Seus elementos e seu tamanho podem ser alterados após a criação. Listas são definidas usando colchetes [],
com os elementos separados por vírgulas, como podemos ver a seguir.
python
# Criando listas
2. numeros = [1.0, 2.0, 3.0]
3. misturada = ['texto', 10, True, 3.14]
4. lista_vazia = []
Listas suportam indexação e fatiamento, exatamente como tuplas e strings. Veja!
python
1. print(numeros[1]) # Saída: 2.0
2. print(misturada[0:2]) # Saída: ['texto', 10]
3.
Conforme já visto, as listas também permitem alteração e inclusão de elementos. Confira os comandos no
exemplo a seguir.
python
1. numeros[0] = 5.0
2. print(numeros) # Saída: [5.0, 2.0, 3.0]
3. #Adicionar elementos
4. numeros.append(4.0)
5. print(numeros) # Saída: [5.0, 2.0, 3.0, 4.0]
6. numeros.insert(1, "olá") # Insere olá na posição 1
7. print(numeros) # Saída: [5.0, olá, 2.0, 3.0, 4.0]
Uso de operadores em sequências
Listas e tuplas permitem o uso dos operadores + (concatenação) e * (repetição), que também funcionam com
strings. Como strings e tuplas são imutáveis, essas operações geram novas sequências. Já as listas, além de
criar novas, podem ser modificadas diretamente.
Neste exemplo, vemos a aplicação tanto da concatenação como da repetição.
python
1. # Concatenação
2. s1 = "Olá "
3. s2 = "mundo"
4. print(s1 + s2) # Saída: Olá mundo
5.
6. lista_a = [1, 2]
7. lista_b = [3, 4]
8. print(lista_a + lista_b) # Saída: [1, 2, 3, 4]
9.
10. # Repetição
11. print("Eco! " * 3) # Saída: Eco! Eco! Eco!
12. print([0] * 5) # Saída: [0, 0, 0, 0, 0]
13.
Atividade 2
Considere os comandos em Python:
python
1. minha_lista = [10, 20, 30]
2. minha_tupla = (10, 20, 30)
Qual das operações a seguir, se executada após a definição das variáveis, causaria um erro em Python?
A print(minha_lista[0])
B print(minha_tupla[1])
C minha_lista[0] = 5
D nova_lista = minha_lista + [40]
E minha_tupla[0] = 5
A alternativa E está correta.
As tuplas são imutáveis, ou seja, uma vez criadas seus elementos não podem ser alterados.
Modularidade e controle de fluxo em Python
Assista a este vídeo e aprenda a organizar programas em Python. Veja como criar funções para reutilizar
código, usar estruturas condicionais (if, elif, else) e aplicar laços for com range() para repetições. Conheça
também a importação de bibliotecas e um exemplo básico de plotagem de gráficos.
Conteúdo interativo
Acesse a versão digital para assistir ao vídeo.
Saber como organizar e controlar a execução de código em Python, introduzindo o conceito de modularidade
por meio da importação de bibliotecas e criar funções personalizadas são conceitos importantes no
aprendizado da linguagem. Usar estruturas de controle de fluxo como condicionais e laço de repetição
também são essenciais.
Funções
Quando um trecho de código precisa ser executado repetidamente, ou quando queremos organizar
logicamente uma tarefa específica, podemos criar nossa própria função. Funções permitem agrupar um bloco
de código, dar um nome a ele e executá-lo quantas vezes quisermos, opcionalmente passando valores de
entrada (argumentos/parâmetros) e recebendo um valor de saída (retorno). A estrutura para definir uma
função em Python é:
python
def nome_da_funcao(parametro1, |parametro2, ...):
Declarações
return valor-de-retorno
Note que nessa estrutura de definição de uma função, a indentação (espaçamento no início da linha) é
importante em Python, pois define quais linhas pertencem ao bloco da função. Conforme pode ser visto a
seguir, a função somar está definida entre as linhas2 e 5. Na linha 8, chamamos a função passando os valores
que queremos somar.
python
1. # Exemplo de função simples
2. def somar(a, b):
3. "Esta função recebe dois números e retorna sua soma."
4. s = a + b
5. return s
6.
7. # Chamando a função
8. valor = somar(5, 3)
9. print(valor) # Saída: 8
Estruturas condicionais (if, elif, else)
Permitem que o programa tome decisões e execute blocos de código diferentes com base em condições
booleanas (verdadeiras ou falsas). A construção de uma estrutura de condicionais no Python é dada por:
python
if condições :
bloco de instruções
elif condições:
bloco de instruções
else:
bloco de instruções
O exemplo a seguir é uma aplicação da estrutura if, em que o script decide se o número é positivo, negativo
ou zero.
python
1. # Exemplo: Verifica o sinal de um número
2. def sinal_numerico(numero):
3. if numero 0: # 'elif' é a contração de 'else if'
6. sinal = 'positivo'
7. else: # 'else' captura o caso restante (numero == 0)
8. sinal = 'zero'
9. return sinal
10.
11. a = -10
12. print(f"O número {a} é {sinal_numerico(a)}") # Saída: O número -10 é negativo
Laços (for) e a função range
Laços permitem repetir a execução de um bloco de código várias vezes. O laço for em Python é usado para
iterar sobre os itens de uma sequência (como uma lista ou tupla) ou sobre uma série de números gerada pela
função range (). A função range (início, parada, passo) gera uma sequência de inteiros.
python
1. # Exemplo de laço for
2. print("Contando de 1 a 5:")
3. for i in range(1, 6): # range(1, 6) gera 1, 2, 3, 4, 5
4. print(i)
5.
6. # Calculando a soma dos primeiros 4 inteiros positivos
7. soma_total = 0
8. for numero in range(1, 5): # range(1, 5) gera 1, 2, 3, 4
9. soma_total = soma_total + numero
10. print(f"A soma é: {soma_total}") # Saída: A soma é: 10
Na linha 3, a função range () cria uma sequência de 1 a 5. A cada iteração do for são impressos os valores na
linha 4.
Gráficos
Uma aplicação comum da modularidade é a criação de gráficos. Bibliotecas como matplotlib são usadas em
conjunto com numpy para operações numéricas eficientes que permitem visualizar dados e funções. Embora
uma explicação detalhada fuja deste escopo inicial, a estrutura básica envolve importar as bibliotecas, gerar
os dados. Veja o código a seguir.
python
1. # Estrutura básica para plotar y = x^2
2. import numpy as np
3. import matplotlib.pyplot as plt
4.
5. x = np.linspace(-2, 2, 100) # 100 pontos entre -2 e 2
6. y = x**2 # Calcula y para cada x
7.
8. plt.plot(x, y) # Cria o gráfico
9. plt.xlabel("Eixo X") # Rótulo do eixo x
10. plt.ylabel("Eixo Y") # Rótulo do eixo y
11. plt.title("Gráfico de y = x^2") # Título
12. plt.grid(True) # Adiciona grade
13. plt.show() # Mostra o gráfico
Na linha 2 importamos a biblioteca numpy usando o comando import e apelidando-a de np. Esta é muito
usada em computação numérica e científica. Já na linha 3, importamos a biblioteca matplotlib.pyplot usando o
mesmo comando. Trata-se de um “submódulo” da biblioteca matplotlib, muito utilizado para geração de
gráficos e visualizações de dados em Python.
Na linha 5, usamos np.linspace(-2, 2,100) para gerar 100 valores igualmente espaçados entre -2 e 2, que são
atribuídos à variável . Na linha 6, calculamos , ou seja, o quadrado de cada valor de x. Na linha 8,
usamos plt.plot( x , y) para criar o gráfico de linha com os valores de x e y. O gráfico é exibido na linha 13 com
plt.show(). Veja a exibição do gráfico gerado.
Conteúdo interativo
Acesse a versão digital para ver mais detalhes da imagem
abaixo.
Representação gráfica da função.
Atividade 3
Observe o seguinte trecho de código Python:
python
1. soma = 0
2. for numero in range(1, 5):
3. soma = soma + numero
4. print(soma)
5.
Qual será o valor impresso na tela como resultado da execução desse código?
A 4
B 5
C 9
D 10
E 15
A alternativa D está correta.
A variável soma começa com o valor 0. Dentro do laço, em cada iteração, o valor atual de número é
adicionado à soma.
Iteração 1: número é 1 . soma vira .
Iteração 2: número é 2. soma vira .
Iteração 3: número é 3. soma vira .
Iteração 4: número é 4. soma vira .
•
•
•
•
2. Representação numérica de erros na aritmética em pontos flutuantes
Representação de números inteiros
Descubra neste vídeo como os números inteiros são representados nos sistemas decimal, binário, octal e
hexadecimal. Entenda a notação posicional e veja exemplos práticos de como decompor números em
potências da base.
Conteúdo interativo
Acesse a versão digital para assistir ao vídeo.
Entender como representamos números inteiros é importante para atuar em áreas ligadas à computação e à
matemática aplicada. Esse conhecimento permite assimilar como os computadores armazenam e processam
informações numéricas, principalmente em diferentes bases, como decimal, binária, octal e hexadecimal.
Compreender como os números são convertidos entre bases e qual sua estrutura ajuda a evitar erros em
operações computacionais.
Representação dos números inteiros positivos
Os sistemas de numeração posicionais são indispensáveis para o entendimento da formação dos números nas
chamadas bases de numeração. A representação dos números inteiros positivos na base decimal (base 10)
utiliza uma sequência de algarismos do conjunto \{0, . O valor que cada algarismo
representa depende da sua respectiva posição na sequência. Neste sistema de numeração, a posição do
dígito indica qual potência base (10) deve ser multiplicada pelo valor daquele dígito.
Exemplo
O número 1981 significa uma (1) unidade de milhar mais (9) centenas (100) mais oito (8) dezenas (10) e
uma (1) unidade, ou, de forma simplificada, por símbolos matemáticos: 1981 = . Para números muito
grandes, essa forma pode ocupar muito espaço. Fazer uso de potência de 10 torna essa representação
mais compacta e adequada matematicamente. Ou seja, . É necessário lembrar que .
Agora, vamos generalizar essa notação matemática. Para isso, vamos adotar como representação para
qualquer dígito numérico decimal a letra , em que i é a posição no número com n+1 dígitos. Por
exemplo, no número 1981 tem 4 dígitos, logo o maior índice da posição é , pois, , o que leva a
. O dígito decimal 1 encontra-se na posição ; 9 na posição ; 8 na posição e
1 na posição . Em uma forma de notação matemática na base 10 temos:
Em que:
Voltando ao exemplo e observando a notação matemática,
você pode notar que o índice i está relacionado à potência aplicada a base decimal (10).
Outra notação comum para representar um número inteiro positivo na base 10 é .
Essa notação nos leva a outra, caso se deseje representar o número com uma base diferente de 10, que seria
, com sendo uma base diferente de 10.
Consequentemente, teremos:
Assim, um número N não nulo possui uma única representação em função da base escolhida:
A base mais comum na aritmética computacional é a binária, em que . No entanto, os valores expressos
nessa base poderão ser representados em outras bases quando houver a necessidade de promover uma
melhor visualização e compactar os seus valores. Geralmente, são usadas as bases 8 (octal) e 16
(hexadecimal), pois ambas são múltiplas de 2.
A base indica a quantidade de símbolos usados em um sistema de numeração posicional, ou seja, o total de
dígitos disponíveis para representar os números. Observe que, para , por definição, os valores
possíveis de são 0 ou 1; de maneira análoga, quando , os valores que esta base pode assumir são: 0
, 1, 2, 3, 4, 5, 6 e 7 . Para os dígitos maiores que 9, adotamos as letras do nosso alfabeto, ou seja,
.
Nesse caso, para a base hexadecimal , os dígitos possiveis são ,
e , em que corresponde, na base decimal, ao número 10, corresponde ao 11, e assim
sucessivamente,até , que corresponde ao 15. Vejamos alguns exemplos:
Observe que o índice i está relacionado à potência aplicada nas respectivas bases.
Atividade 1
O sistema de numeração decimal é o que mais usamos no nosso dia a dia para representar números. Como o
número 179 na base decimal (10) é decomposto de acordo com a notação matemática que considera a
posição de cada algarismo?
A 1 + 7 + 9
B 1×10⁰ + 7×10¹ + 9×10²
C 1×10² + 7×10¹ + 9×10⁰
D 17×10¹ + 9×10⁰
E 1×10³ + 7×10² + 9×10¹
A alternativa C está correta.
Neste sistema de numeração, a posição do dígito indica qual potência base (10) deve ser multiplicada pelo
valor daquele dígito. Para o número 179, temos:
(posição 2), índice 2
(posição 1), índice 1
(posição 0 ), índice 0
Aplicando a fórmula: .
Conversão entre os sistemas de numeração
Aprenda neste vídeo a converter números inteiros entre diferentes bases. Veja como transformar uma base
qualquer para decimal e do decimal para binária, octal ou hexadecimal usando o algoritmo da divisão. Também
descubra como fazer essas conversões no Python.
Conteúdo interativo
Acesse a versão digital para assistir ao vídeo.
Embora os sistemas de computação expressem e realizem operações com seus valores na base 2 (binária),
eles poderão ser representados em outras bases quando houver a necessidade de melhorar visualização.
Dominar esse procedimento é importante para possibilitar a alternância entre os sistemas de numeração.
Agora, veja como são convertidos os valores entre bases numéricas distintas.
Mudança da base b para a base decimal 10
A conversão de um número inteiro positivo, que se encontra em uma base numérica b para a base decimal
(10), é possível por meio da solução da seguinte expressão:
N terá outros dígitos na base 10, como veremos a seguir. Nestes exemplos, vamos converter para base
decimal (10) os números representados nas bases. Vamos lá!
Binário Octal
Hexadecimal
Observe adiante.
Mudança da base 10 para a base b
Para converter um número inteiro positivo N na base , para uma base , é necessário determinar
os seus respectivos dígitos , de modo que se tenha a representação:
Para entender o procedimento, devemos nos lembrar do algoritmo da divisão de números inteiros positivos,
em que, ao dividir um número D por um número p, obtém-se um quociente e um resto ; e quando ,
dizemos que a divisão foi exata e o resto só pode assumir os valores de . Formalizando por
símbolos matemáticos:
Voltando à expressão:
Nosso objetivo é determinar os dígitos . Assim, pelo princípio da igualdade:
Lembrando que e pelo algoritmo da divisão de números inteiros positivos podemos representar N
como:
Em que foi posto em evidência. Logo:
Da mesma forma, o resto da divisão de:
Repetindo esse processo encontramos os dígitos: na base b, de modo que o quociente
da n-ésima e última divisão será o . Ou seja, para transformar um número N na base decimal (10) em
qualquer base b, basta obter o resto da divisão deste número N pela base a ser transformada.
Vamos realizar alguns exemplos convertendo da decimal para as bases binária, octal e hexadecimal. Para
realizar essa transformação, executaremos o procedimento do algoritmo da divisão dos números inteiros.
Então, pela notação:
Observe a seguir o processo manual de mudança da base decimal para binária.
Conteúdo interativo
Acesse a versão digital para ver mais detalhes da imagem
abaixo.
Note que os dígitos da base binária são obtidos pelo resto da divisão sucessiva do número a ser
transformado. A seta em azul indica a ordem da formação dos dígitos na nova base.
Agora, conheça o processo manual de mudança da base decimal para octal.
Conteúdo interativo
Acesse a versão digital para ver mais detalhes da imagem
abaixo.
Note que os dígitos da base octal são obtidos pelo resto da divisão sucessiva do número a ser transformado.
A seta em azul indica a ordem da formação dos dígitos na nova base.
Acompanhe o processo manual de mudança da base decimal para hexadecimal:
Conteúdo interativo
Acesse a versão digital para ver mais detalhes da imagem
abaixo.
Prosseguindo com o mesmo raciocínio, observe!
Confira o processo manual de mudança da base decimal para hexadecimal.
Conteúdo interativo
Acesse a versão digital para ver mais detalhes da imagem
abaixo.
Para transformar um número da base decimal para outra base, realizamos divisões sucessivas desse número
pela base desejada, até que o quociente seja zero. A representação na nova base é formada pelos restos
obtidos em cada divisão, lidos de baixo para cima.
Em Python, esse processo de conversão de base é muito simples. Observe o trecho de código no qual é
solicitado a entrada de um número na base decimal e a saída exibe esse número nas bases: binária, octal e
hexadecimal.
python
1. # Solicita ao usuário um número decimal
2. decimal = int(input("Digite um número decimal: "))
3.
4. # Conversões de base
5. binario = bin(decimal) # binário
6. octal = oct(decimal) # octal
7. hexadecimal = hex(decimal) # hexadecimal
8.
9. # Exibe os resultados
10. print(f"Binário: {binario}")
11. print(f"Octal: {octal}")
12. print(f"Hexadecimal: {hexadecimal}")
Na linha 2, a variável decimal recebe o valor decimal que é transformado em inteiro pela função int(). Entre as
linhas 5 e 7 são aplicadas as funções bin(), oct() e hex() que realizarão as conversões. Entre as linhas 10 e 12
são impressos os resultados.
Bits e representação dos números inteiros negativos
Define-se como bit (binary digit) o elemento de memória básico de um
computador que assume dois estados, representados pelos dígitos
zero (0) e um (1). O número de bits disponíveis para uma representação
numérica de inteiros positivos corresponde ao maior inteiro que o
computador pode representar, ou seja, com bits é possível
representar números. Por exemplo, para representar os oito dígitos
decimais, seriam necessários três bits, pois , entretanto, para
representar 10 dígitos decimais são necessários quatro bits, pois
16 configurações, o que é excedente, ou seja, no sistema decimal há
desperdício de bits.
Sequência de números no sistema binário
(0 e 1).
Atenção
No contexto do sistema de numeração posicional, a representação dos números inteiros não positivos é
realizada utilizando a ideia do bit, ou seja, são convencionadas para os sinais positivo ( + ) ou negativo (
- ) as representações de zero ( 0 ) ou um (1) respectivamente. O único problema dessa representação
ocorre em operações para obter os números +0 e - 0 , que, embora para o computador sejam números
diferentes, sabemos que são iguais.
Vamos a um exemplo de representação de números inteiros com sinal utilizando o método sinal-magnitude
com número decimal . Neste método, o bit mais à esquerda é o bit de sinal, o restante são
os bits de magnitude.
Vimos que e foram usados 6 bits. Com isso, podemos adicionar um bit 0 ou 1 mais à
esquerda para indicar que se trata de um número positivo ou negativo.
Assim, e . Observe que cada representação tem 7 bits.
Outras metodologias, como complemento de 1 e complemento de 2, não serão abordadas neste estudo.
Atividade 2
Com relação ao procedimento de conversão de base, como o número seria representado na base
binária ?
A 11110111101
B 11100111101
C 11110111
D 101101
E 11110001
A alternativa A está correta.
Vamos lá!
Pois, pelo algoritmo da divisão, temos:
Representação dos números reais
Descubra neste vídeo como representar números reais — parte inteira e fracionária — em diferentes bases.
Veja como converter entre decimal e outras bases, além de conhecer a notação científica normalizada e a
representação em ponto flutuante usada pelos computadores.
Conteúdo interativo
Acesse a versão digital para assistir ao vídeo.
A representação de números reais no computador é essencial, mas traz desafios diferentes dos inteiros. É
importante entender como números com parte fracionária são expressos em várias bases, usando potências
negativas da base. Aqui serão apresentadosos métodos de conversão entre decimal e outras bases, como a
binária, para explicar o uso da notação científica e da representação em ponto flutuante no tratamento desses
números.
Para nossa análise inicial, um número real pode ser visto como composto por uma parte inteira e uma parte
fracionária: , sendo:
É a parte inteira. É a parte fracionária.
Por exemplo, o número 95,32, em que e f=0,32. Este pode ser representado na base decimal (10), da
seguinte maneira:
Agora, vamos generalizar essa ideia: um número real na base dez (10), com dígitos na parte inteira e
m dígitos na parte fracionária, pode ser representado como:
Utilizando o mesmo raciocínio, um número real , representado em uma base b, pode ser escrito da seguinte
maneira:
Usando esse conceito de representação nas bases binárias, octal e hexadecimal teremos as seguintes
representações:
Mudança de base 10 para a base b
Para converter um número real da base 10 para a base b, considerando o formato . Tomando como
exemplo 95,32, podemos representá-lo como a soma da parte inteira com a parte real. O número 95,32 pode
ser escrito como . Assim, o número real .
Já vimos a transformação da parte inteira; agora, focaremos somente a parte fracionária . Então, vamos
considerar que o nosso número real só contém a parte fracionária:
O procedimento seria, primeiramente, lembrar que, para transformar um inteiro na base (10) para uma base b,
deveríamos dividir o número por b, sucessivamente, e obter os restos. A ideia será a mesma, porém com uma
diferença: ao contrário de fazer divisões, faremos multiplicações, ou seja, o primeiro passo será multiplicar o
número real pela base que se deseja transformar, b. Em símbolos matemáticos, teríamos:
Obtém-se uma parte inteira, , e a parte fracionária começa com . Multiplicando agora a parte
fracionária restante novamente pela base b, o resultado será , e, assim, sucessivamente, até obter todos
os dígitos. A seguir, veja a conversão do número real 0,625 para a base binária .
Note que o critério de parada é quando obtemos 0,000 na parte fracionária. Então, .
Vamos considerar agora um número 9,625, composto por uma parte inteira diferente de zero e uma parte
fracionária. Inicialmente, iremos decompô-lo na soma de suas partes inteira e fracionária.
Por exemplo: . Para converter a parte inteira 9, fazemos sucessivas divisões por .
Então, , e a parte fracionária, já calculada anteriormente, é . Unindo
as duas partes, considerando , temos .
Vamos a mais um exemplo!
Primeiro, vamos dividir esse número em parte inteira e parte fracionária. Logo, = .
Convertendo a parte inteira 10 para base 8, teremos:
Assim, . Aplicando agora a conversão da parte fracionária 0,25, teremos .
Note que . Então, .
Mudança da base b para a base 10
Seja um número real na base . Para obter a sua representação na base 10, basta
aplicar a fórmula matemática:
Por exemplo, converter o número para a base 10, aplicando a fórmula:
Convertendo agora o exemplo para base 10.
Notação científica dos números reais
Nas ciências, é comum lidar com valores muito grandes ou muito pequenos. Por exemplo, na astronomia, a
distância até a estrela mais próxima depois do Sol é de cerca de 40.208.000.000.000 km. Já na
nanotecnologia, o diâmetro típico de um nanotubo de carbono pode ser de apenas 0,000000001 metro. Para a
representação desses números, é necessária uma quantidade grande de dígitos. A solução desse problema é
usar a notação científica, cuja representação de um número real é dada da seguinte forma:
Em que:
É um inteiro real não negativo, chamado de
mantissa.
É um número inteiro positivo, chamado de base.
É chamado de expoente.
No entanto, essa notação possui uma ambiguidade. O número 0,1, por exemplo, pode ser representado de
formas equivalentes:
Para resolver essa situação, foi imposta a seguinte condição à mantissa:
Essa condição define uma notação normalizada. Com base nessa condição, o número 0,1 normalizado seria
. Usando o exemplo da distância do sol: 40.208.000.000.000 km, na escrita científica geral, esse
número é escrito como , em que . No entanto, para manter a
notação normalizada precisamos ajustar a mantissa M de modo que . Movendo a vírgula
decimal para a esquerda até que ela fique imediatamente antes do primeiro dígito diferente de zero, a
mantissa M se torna 0,40208 e .
Ambas as formas representam o mesmo valor. No entanto, elas seguem convenções de normalização
diferentes. A primeira é mais comum na escrita científica geral, enquanto a segunda
é mais relevante para entender como alguns sistemas computacionais padronizam a mantissa
em ponto flutuante. Cada regra garante uma representação única para o número, resolvendo o problema da
ambiguidade.|
Representação em ponto flutuante
A notação científica abrange todos os números reais e, como sabemos, essa quantidade é infinita, o que torna
impossível de ser implementada em um computador que possua uma quantidade finita de dígitos. A solução
foi modificar um pouco a normalização da notação científica da seguinte maneira:
Mantissa
Alterar para um número finito de dígitos.
Expoente
Criar um intervalo para o expoente, ou seja, o
expoente e possui um valor mínimo e
um valor máximo .
A notação que usaremos é , para nos referirmos ao número no sistema de ponto flutuante
de base , na qual a mantissa possui dígitos (na base b) e os expoentes estão contidos no intervalo
fechado , ou seja, ou onde .
Exemplo
Um número real representado em ponto flutuante pode ser escrito de forma genérica como , em que .
Observe que essa representação não é capaz de representar o número real , pois o expoente é igual a ,
que é o expoente máximo. O mesmo para o número .
No primeiro caso ocorre overflow, quando o valor excede o maior número que pode ser representado. No
segundo ocorre underflow, quando o valor é menor que o menor número representável. Considere o sistema
, em que .
Assim, número como pode ser representado, pois é maior que -2 e menor
que 2. No entanto, o número não poderia ser representado neste sistema, pois
é maior que 2, além também de ter 4 dígitos.
Embora estejam relacionadas, notação científica e ponto flutuante não são exatamente a mesma
coisa. A notação científica é usada para representar números muito grandes ou muito pequenos na
base decimal. Já o ponto flutuante é uma forma de armazenar números reais no computador, com
base binária, geralmente utilizando o padrão IEEE 754, que representa os números com três partes:
sinal, expoente e mantissa.
No Python, números reais (float) são tratados como ponto flutuante, pois é possível controlar sua exibição
usando formatações. Por exemplo, a formatação :.nf é usada para exibir um número em ponto flutuante, mas
arredondado para n casas decimais.
python
1. x = 3.14159
2. print(f"{x:.0f}")
3. print(f"{x:.1f}")
4. print(f"{x:.2f}")
Ao executar o trecho de código para e , as saídas serão respectivamente: 3, 3.1 e 3.14.
Atividade 3
Considere o sistema de ponto flutuante, normalizado na forma , com e . Qual dos
seguintes números excede as limitações de representação por overflow ou underflow neste sistema?
A 0.0213
B 98.7
C 423.4
D 0.00567
E -0.111
A alternativa C está correta.
Vamos analisar cada alternativa de acordo com as regras do sistema e a normalização
com . Com isso, temos, :
(A) 0.0213: Normalizado: , Mantissa ( 0.213 ) tem dígitos. . Expoente e
. Verificamos o intervalo: . O expoente está dentro do intervalo permitido.
(B) 98.7: Normalizado: . Mantissa (0.987) tem dígitos. . Expoente .
Verificamos o intervalo: . O expoente está dentro do intervalo permitido.
(C) 423.4: Normalizado: . Com precisão , a mantissa seria 0.423 . .
Expoente . Verificamos o intervalo: é maior que 2 . Não representável devido a Overflow.
(D) 0.00567: Normalizado: . Mantissa ( 0.567 ) tem dígitos. . Expoente e
. Verificamos o intervalo: . O expoente está dentro do intervalo permitido.
(E) -0.111: Normalizado: . Mantissa (0.111) temdígitos. . Expoente 0
. Verificamos o intervalo: . O expoente está dentro do intervalo permitido.
Portanto, o único número que não pode ser representado no sistema devido às limitações
do expoente (overflow) é 423.4.
Erros na aritmética em pontos flutuantes
Descubra neste vídeo por que nem sempre os números reais são representados com exatidão no computador
e quais erros isso pode causar, como o arredondamento por truncamento ou aproximação. Veja ainda como
calcular e interpretar o erro absoluto e o erro relativo para avaliar a precisão dos valores numéricos.
Conteúdo interativo
Acesse a versão digital para assistir ao vídeo.
A representação numérica em computadores raramente é exata, introduzindo inevitavelmente erros nos
cálculos. Essa imprecisão manifesta-se como erros de arredondamento ou erros de truncamento.
Compreender e quantificar esses desvios é necessário para avaliar a confiabilidade das soluções
computacionais. Para tal, utilizamos métricas consideráveis como o erro absoluto e o erro relativo, que medem
a exatidão das aproximações obtidas.
Erros de representação
A representação finita dos pontos flutuantes influencia nos números reais. Por exemplo, se verificarmos no
Python se , a resposta será verdadeira, mas quando verificamos se , a resposta é falsa.
Faça você mesmo essa verificação replicando o código a seguir.
python
1. import math
2. print(2**2 == 4)
3. print(math.sqrt(5)**2 == 5)
Saída: True
False
A representação em pontos flutuantes só consegue ser realizada de maneira exata para alguns números. Para
outros números reais, poderá indicar algum erro, logicamente supondo que os números não sejam overflow ou
underflow. Assim, a explicação de ser falsa é que math.sqrt(5) retorna uma aproximação
, que quando elevado ao quadrado .
Definiremos um número real, que esteja contido em um sistema ponto flutuante , de
forma exata, de . Caso contrário, obteremos a resposta erro. Caso não seja possível
representar o número real no sistema de ponto flutuante com exatidão, existem duas técnicas possíveis
para obter . Vamos conhecê-las agora!
Arredondamento por truncamento
Dada uma mantissa de um número real , com número de dígitos , em que é o número de
dígitos do sistema de ponto flutuante, define-se o truncamento ao desprezar todos os dígitos a partir da
posição .
Exemplo
Seja o número real, na sua notação científica na base 10, igual a , se o representarmos em um sistema de
ponto flutuante , então, o resultado será . Note que neste exemplo , então a partir da posição , ou seja, a
partir da posição 5 todos os dígitos foram desprezados.
Arredondamento por aproximação
Essa técnica é a mais comum e tem por objetivo reduzir o erro entre o ponto flutuante e o valor exato
, ou seja, o valor mais próximo. Utilizando o exemplo anterior , o 5º dígito após a
vírgula é 9. Como 9 é maior ou igual a 5, arredondamos o dígito da posição para cima. Então, 0,3415
vira 0,3416. Com isso, aproximar para tem um erro menor que aproximar para o valor
truncado.
Para calcular esse erro, vamos usar do valor absoluto representado pelo símbolo: | |, que tem a função de:
Se o número dentro das barras for positivo ou zero, ele permanece igual.
Se o número dentro das barras for negativo, ele se torna positivo.
Logo, o resultado de é sempre não negativo e o erro é computado por: .
Erro para o valor truncado Erro para valor arredondado
Nesse exemplo, você pode ver que o erro por arredondamento por aproximação (0,000211) é menor que o
erro por arredondamento por truncamento (0,000789).
O critério de arredondamento por aproximação, às vezes, pode apresentar uma ambiguidade. Por exemplo,
quando o número real 0,15 for arredondado para um dígito (uma casa decimal), os números 0,1 e 0,2 estão
igualmente próximos. Para resolver esse problema, foram desenvolvidas várias soluções e, para o sistema
binário ( ) e decimal ( ), a mais comum é arredondar de forma que o último dígito seja par.
Agora, veja um exemplo para essa regra considerando o arredondamento com uma casa decimal.
Seja . Esse número está exatamente na metade entre 1,3 e 1,4. O dígito a ser mantido se
arredondarmos para baixo é 3, que é ímpar em 1,3. Pela regra, se o dígito for ímpar, arredondamos para cima
para que o novo último dígito seja par. Assim, arredondar 1.35 para cima resulta em 1.4.
Atenção
Quando fazemos arredondamentos, seja por truncamento ou por aproximação, a alteração ocorre
apenas na mantissa. O expoente permanece inalterado, o que significa que não há erro associado a ele
nesse processo.
Erro absoluto e erro relativo
Agora, podemos analisar os erros de representação de um número real e sem perda de generalidade. Vamos
considerar somente os números reais positivos exatos na notação científica normalizada, ou seja,
e o seu correspondente no sistema de ponto flutuante , não necessariamente
normalizada. Define-se como erro absoluto por:
•
•
Em termos práticos, imagine que o valor exato representado na forma decimal seja . Se um
sistema de ponto flutuante só consegue armazenar 4 casas decimais e trunca (corta) o restante, ele
armazenaria . O erro absoluto seria:
O erro absoluto quantifica o quão longe a representação armazenada pelo computador está do valor
real, podendo não dar a devida importância ao erro. O conceito de erro relativo normaliza o erro, colocando
em uma nova perspectiva. Define-se como erro relativo :
Por exemplo:
Considere e sua aproximação .
O erro absoluto é .
Já o erro relativo .
Vamos analisar a relação entre o erro absoluto e o erro relativo.
Exemplo
Se (um milhão) e o erro absoluto , o erro absoluto parece pequeno. O erro relativo seria , que significa .
Isso indica que o erro é muito pequeno em comparação com o valor total. Agora, se e o erro absoluto , o
erro absoluto é o mesmo do exemplo anterior. No entanto, o erro relativo é e = 1/2 = 0,5, que representa
50%. Isso indica que o erro é extremamente significativo em comparação com o valor total.
Atividade 4
Um usuário solicita a um sistema uma informação de crédito. Ele coloca como entrada o valor
e que, por um processo computacional, foi obtido um valor aproximado de 2346,000. Ele solicita o cálculo do
erro entre o valor real e o valor aproximando. O sistema só pode retornar 3 casas decimais para o erro
absoluto usando aproximação por truncamento e 8 casas decimais para erro relativo aplicando
arredondamento por aproximação respectivamente. Com base nisso, quais são os erros absoluto e relativo
respectivamente?
A 0.710 e 0.00250000
B 0.716 e 0.00031340
C 0.731 e 0.00030396
D 0.713 e 0.00030395
E 0.713 e 0.00030396
A alternativa E está correta.
e
Para calcular o erro absoluto, calculamos
0,7130000000001928 . Aplicando o arredondamento por truncamento, teremos: 0,713. Para calcular o erro
relativo, basta fazer .
Considerando que o sistema usa 8 casas decimais, temos , pois na posição 9 temos o
digito 8, que é maior que 5.
Erros nas operações aritméticas
Confira neste vídeo como as operações de soma, subtração, multiplicação e divisão com números em ponto
flutuante podem gerar e propagar erros. Entenda o impacto do alinhamento de expoentes, a perda de precisão
e o cancelamento catastrófico, além de seus efeitos nos cálculos computacionais.
Conteúdo interativo
Acesse a versão digital para assistir ao vídeo.
A aritmética de ponto flutuante afeta a representação de números e introduz erros durante as operações
matemáticas básicas. Entender como as operações de soma, subtração, multiplicação e divisão realizadas
dentro das limitações de um sistema de ponto flutuante geram desvios dos resultados exatos é de extrema
importância.
Além da representação imprecisa de números, a própria aritmética realizada em um computador não é exata,
introduzindo erros adicionais durante as operações principais de soma, subtração, multiplicação e divisão.
Uma descrição simplificada de como o sistema de ponto flutuante realiza essas operaçõesajuda a entender
as fontes desses desvios. Para a soma e subtração de dois números no mesmo sistema de ponto flutuante,
temos:
Em que , e sua soma e subtração podem ser dadas pelas expressões a seguir.
E agora:
Note que para executar a soma ou a subtração o expoente c precisa ser ajustado de modo que
e pelo fato . Ou seja, precisamos que ambos os termos tenham o mesmo expoente.
Nesse caso, a soma ou a subtração é realizada entre e (ajustado).
Agora, vamos analisar um exemplo em que será considerado o sistema de ponto flutuante na base decimal (
), (mantissa m pode ter apenas 4 dígitos significativos). Para a normalização usaremos a forma
, em que .
Considere (ou seja, 654300 ), em que e . E (ou
seja, 789.1), em que e expoente de é c-a . Então, ajustado
torna-se 0,007891.
Logo . É necessário lembrar que a nossa precisão é
. Aplicando o arredondamento por truncamento .
Vamos agora verificar o erro relativo nesta operação.
De maneira análoga, o mesmo procedimento ocorre para a operação de subtração quando os expoentes são
os mesmos. Lembrando que as operações com mesmo expoente a adição e a subtração são triviais.
Soma
Subtração
Atenção
Computacionalmente, é mais eficiente ajustar a mantissa, de modo que o número com o menor expoente
se alinhe com o de maior expoente, o que envolve deslocar a mantissa do número menor para a direita.
Esse deslocamento faz com que dígitos menos significativos de sejam perdidos, mas evita o risco de
overflow que ocorreria ao deslocar a mantissa do número maior para a esquerda.Para a multiplicação e
divisão, não temos o mesmo problema de ajustar os expoentes. Basta apenas aplicar as propriedades
existentes de potenciação.
Multiplicação
Um dos pontos de atenção na multiplicação é que a soma dos expoentes pode gerar um underflow se for
maior que ou overflow se for menor que . Outro ponto crítico ocorre na multiplicação das
mantissas e , que é a principal fonte de erro de representação, uma vez que pode aumentar
consideravelmente a quantidade de dígitos permitidos no sistema.
Algebricamente, representamos como:
Vamos considerar nosso sistema de ponto flutuante da seguinte forma: .
Tomemos como exemplo e . Então,
. Aplicando a normalização, chegamos a .
Note que a mantissa tem 7 dígitos comparado com 4 dígitos significativos iniciais de e
. O sistema permite apenas 4 dígitos, consequentemente, o resultado final no sistema de ponto flutuante é:
Nessa operação, 3 dígitos foram descartados produzindo um erro relativo, .
Atenção
Se o sistema fosse definido, por exemplo, como , então um expoente causaria overflow.
Vejamos em Python esse efeito do erro em virtude da precisão na operação de multiplicação no trecho de
código a seguir.
python
1. import math
2. a = math.sqrt(5)
3. print(a*a) # saída 5.000000000000001
Ao executar o trecho de código, a saída não será o número 5, mas 5,000000000000001. Então, o erro relativo
será:
Divisão
As mesmas preocupações referentes a operação de multiplicação também devem ser observadas na
operação de divisão como overflow e underflow. No entanto, a divisão das mantissas pode ocasionar
erro, uma vez que este quociente pode ter um número infinito de dígitos, por exemplo, em . Sua
representação algébrica é:
Vamos a um exemplo usando o mesmo sistema de ponto flutuante da operação de multiplicação.
Considere e .
A divisão , que produz um resultado com infinitos dígitos.
Este resultado já está normalizado. Mantendo a precisão de (lembrando que
), uma vez que foi realizado o arredondamento por truncamento o erro relativo é:
Cancelamento catastrófico
A subtração entre números muito próximos pode resultar no fenômeno conhecido como cancelamento
catastrófico, que causa perda significativa de precisão numérica devido à eliminação de dígitos importantes.
Considere o mesmo sistema de ponto flutuante usado na adição ( ). Seja e
. A subtração exata é y . Na forma normalizada exata
é y . Como e . Então,
. Na forma normalizada é (precisão
dígitos).
Como na operação de adição, vamos calcular o erro da subtração. Dessa vez, além do erro relativo, também
calcularemos o erro absoluto.
Erro absoluto
Erro relativo
.
Aproximadamente .
Note que o erro relativo é maior que o erro absoluto. Esse problema é muito comum quando fazemos
subtrações com números muito próximos entre si.
Atenção
O erro de cancelamento catastrófico pode ter consequências inesperadas em cálculos computacionais,
pois leva a uma perda drástica de dígitos corretos no resultado da subtração. Isso pode ocasionar
resultados numéricos completamente errados, como nas falhas em testes de convergência usada em
algoritmos iterativos aplicados para encontrar raízes de funções, que param quando a diferença entre
duas iterações sucessivas é pequena.
Existem técnicas para diminuir o cancelamento e uma delas é acrescentar 1 ou 2 dígitos na representação do
número arredondado no sistema de ponto flutuante utilizado. Essa técnica é implementada no hardware da
unidade de ponto flutuante (FPU - Floating-Point Unit) dos processadores. Ou seja, durante cálculos
intermediários, especialmente durante a adição e subtração, a FPU utiliza alguns bits (ou dígitos, na base 10)
extras além da precisão do formato.
Atividade 5
Considere um sistema de ponto flutuante decimal que utiliza truncamento após as
operações. Sejam dois números exatamente representáveis neste sistema: e
. É correto afirmar que o erro absoluto introduzido pela operação de adição é:
A E = 0
B E = 0,002
C E = 0.008
D E = 0,0089
E E = 0,089
A alternativa B está correta.
Calculando a soma exata . Realizando a soma ajustando as mantissas
em função de igualar os expoentes, temos . Aplicando a precisão ,
truncamos a mantissa para 4 dígitos: 0.7332 . O resultado da operação no sistema:
. Erro Absoluto .
3. Raízes de funções não lineares
Convergência em processos numéricos
Entenda neste vídeo o conceito de convergência, essencial para métodos numéricos que buscam soluções
aproximadas. Veja como processos iterativos, a partir de uma estimativa inicial, ajustam valores até alcançar a
tolerância desejada.
Conteúdo interativo
Acesse a versão digital para assistir ao vídeo.
A convergência é um conceito em métodos numéricos, pois garante que uma sequência de aproximações se
aproxima do valor exato desejado. Ao resolver problemas, utilizamos processos iterativos, nos quais partimos
de um valor inicial, um "chute", e o ajustamos por meio de uma fórmula recorrente. Esse conceito de
convergência torna os métodos numéricos ferramentas indispensáveis na solução de equações não lineares.
Suponha que você queira saber o valor da raiz quadrada de dois ( ). Você consegue estimar que
.
Então, chega à conclusão que . Mas determinar o valor correto já não é tão fácil. Para isso,
precisamos de um método iterativo que segue uma sequência de passos para se aproximar ou determinar o
valor procurado. Para verificar o quão próximo estamos da solução, calculamos a diferença entre a solução
atual e a anterior, ou seja, o erro. Se essa diferença for menor que um valor pequeno predefinido que
denominamos de tolerância, consideramos que nosso método iterativo convergiu para a solução procurada
com a precisão desejada.
Uma técnica iterativa, geralmente, é realizada da seguinte forma:
1. É dado um valor inicial , que, às vezes, chamamos de "chute inicial".
2. É calculado o próximo valor , geralmente, com a seguinte formulação matemática: ,
em que é um passo. O passo pode ser constante ou depender de , ou seja, .
3. São calculados os próximos até o ficar tão pequeno quanto desejamos, normalmente
adotado em uma tolerância (tol). Então, a iteração pode ser dada pela seguinte anotação:
.
Note que obter tão pequeno em relação a uma tolerância tol é determinar que:
tol . Nesse caso, buscamos diminuir o erro entre o passo atual com o passo anterior.
Agora, vamos determinar a usando o método iterativo. Seja x o valorque queremos encontrar, então
, que significa . Podemos transformar esse problema em uma função , de
modo que, para obter a solução, precisamos encontrar , tal que . Vamos construir nosso modelo
iterativo por meio de manipulação algébrica. Considere inicialmente . Somamos ambos os lados por
.
Então, teremos:
Dividindo ambos os lados da igualdade por , teremos:
Que é equivalente a:
Nesse caso, o passo é:
Pelo modo iterativo:
De mãos em nossa formulação iterativa, vamos agora calcular a . Precisamos de um valor inicial . Seja
, então:
Se continuarmos mantendo uma precisão de 4 dígitos, teremos para 1,414 .
A seguir, veja o código Python para esse processo iterativo que pode ser replicado em uma célula do Google
Colab.
python
1. def raiz2(x0, tolerância=1e-6, max_iter=100 ):
2. """
3. Aplica o método de Newton para encontrar a raiz quadrada de 2.
4.
5. Parâmetros:
6. x0 : chute inicial
7. tolerância : critério de parada com base na diferença entre iterações
8. max_iter : número máximo de iterações
9.
10. Retorna:
11. Aproximação da raiz quadrada de 2
12. """
13. for i in range(max_iter):
14. x1 = x0 - (x0**2 - 2) / (2 * x0) # fórmula dada
15. print(f"Iteração {i+1}: x = {x1}")
16. if abs(x1 - x0) = 0:
15
16 return None #f(a) e f(b) não têm sinais opostos!")
17 else:
18 # Loop iterativo em relação a tolerância
19 i = 0
20 while (b - a) / 2.0 >= tol:
21
22 # Calcula o ponto médio
23 z = (a + b) / 2
24
25 # Avalia a função no ponto médio
26 z_m = f(z)
27
28 # Determina o próximo intervalo
29 # Se f(a) e f(z) têm sinais opostos, a raiz está em [a, z]
30 iff(a) * z_m = 0:
3. return None, 0
4.
5. for i in range(1,max_iter+1):
6. # Cálculo do ponto de interseção da reta (falsa posição)
7. x = (f(b)*a - f(a)*b) / (f(b) - f(a))
8.
9. # Cálculo do erro relativo (evita divisão por zero)
10. if i > 1:
11. erro_relativo = abs((x - x_ant) / x)
12. if erro_relativo