Computadores e Programação 2007 2008 Orlando Oliveira, Helmut Wolters adaptado a partir duma apresentação de Fernando Nogueira, José António Paixão, António José Silva orlando@teor.fis.uc.pt, helmut@coimbra.lip.pt Computadores e Programação p.1
Programa O modelo de von Neumann do computador digital. Arquitectura de um computador moderno. Representação digital de dados. Códigos binários para representação de inteiros (código de valor absoluto e sinal e código de complementos de 2), reais (vírgula flutuante), caracteres (ASCII, unicode), imagem (RGB, JPEG) e som (CD-AUDIO). Operações numéricas sobre dados binários. Problemas ligados à imprecisão da representação dos números reais em vírgula flutuante. Processadores. Funcionamento de um CPU. Representação binária do código executável de um programa. Computadores e Programação p.2
Programa Assembladores, compiladores e interpretadores. Linguagens de programação de alto nível e de muito alto nível (VHLL). Sistemas operativos. Introdução à linguagem de programação Python. A instrução de atribuição. Aliasing. Noção de ponteiro. Tipos numéricos: inteiros, inteiros longos, números em vírgula flutuante e complexos. Sequências (listas, tuplas e sequências de caracteres). Iteração sobre sequências e operações de fatiagem (slicing). Abrangências. Dicionários. Instruções de controlo de fluxo: if..elif..else, while..else, for..else. Computadores e Programação p.3
Programa Funções. Espaço dos nomes e regras de alcance. Mecanismo de passagem de argumentos e devolução de valores. Programação funcional e imperativa. Funções puras. As ferramentas de programação funcional lambda, map, filter e reduce. Exemplos de pequenos programas em estilo funcional. Módulos. Ferramentas de introspecção e metaprogramação. Ficheiros. Formatação. Redirecção dos canais de fluxo de entrada e saída. Computadores e Programação p.4
Programa Programação orientada por objectos. Noção de classe e instâncias de classe. Atributos e métodos. Herança, encapsulamento e polimorfismo. Sobrecarga de operadores. Objectos persistentes: módulos pickle e shelve. Excepções. As instruções raise e try..except..finally. Recursão. Iteradores e geradores. Resolução de problemas numéricos de Física e Biomedicina. Computadores e Programação p.5
Avaliação 30 % Resolução de problemas Entrega semanalmente por correio electrónico 30 % Projecto Início de Dezembro, entrega até 1 a semana de Janeiro 40 % Mini testes 31 de Outubro 5 de Dezembro Computadores e Programação p.6
O modelo de von Neumann O matemático Johann von Neumann, consultor do projecto Manhattan, envolve-se nos projectos do ENIAC e do EDVAC em Junho de 1944. Inspirado por estes, concebe um modelo téorico para um computador, que é o modelo adoptado até hoje. O computador é constituído pelas seguintes unidades funcionais: Memória central Unidade aritmética e lógica Unidade de controlo Unidades de entrada e saída Hoje em dia o processador engloba a unidade aritmética e lógica e a unidade de controlo. Computadores e Programação p.7
O modelo de von Neumann Unidade de controlo C C I D Unidade A/L C D Unidades de E/S R D R R Memoria Central Computadores e Programação p.8
O modelo de von Neumann O processador não efectua operações directamente sobre a memória (à excepção da transferência de dados). O processamento é feito em células especiais de memória no interior da UAL denominadas registos. A tranferência de dados entre a memória central e os dipositivos de entrada e saída pode ser feita passando pelo processador ou através de acesso directo à memória (DMA). Computadores e Programação p.9
Informação Digital Os computadores processam informação digital. Grandeza analógica Varia de forma contínua (ex: temperatura lida num termómetro de Hg). Grandeza digital Descontínua (existe apenas um número finito de estados). Elemento mínimo de informação: dígito binário (bit). bit: 2 estados 0 ou 1. Computadores e Programação p.10
Informação Digital Um conjunto de n bits pode tomar 2 n configurações distintos, podendo representar 2 n objectos ou informações elementares. Exemplo com 3 bits: Configurações possíveis (8 = 2 3 ): 000, 001, 010, 011, 100, 101, 110, 111. Podemos utilizar estas combinações de bits para representar de forma unívoca 8 letras do alfabeto: A 000 E 100 B 001 F 101 C 010 G 110 D 011 H 111 Computadores e Programação p.11
Codificação/descodificação Os computadores processam (apenas) informação/dados em formato digital. Todos os dados têm que ser codificados num formato digital para serem passíveis de tratamento informático. Para cada tipo de dado tem de se estabelecer um código que permita atribuir uma configuração binária única a cada dado desse tipo codificação. A operação inversa é a descodificação. Vamos passar em revista alguns dos códigos actualmente usados para representação digital de vários tipos de dados num computador: Números inteiros, Números inteiros relativos Números reais (Caracteres) (Som e imagem) Computadores e Programação p.12
Codificação de inteiros A forma mais simples de representar um número inteiro num formato digital corresponde a utilizar a sua representação binária, isto é, na base 2. O número é representado por n bits a n 1 a n 2 a 0 onde a i = 0, 1 e i = 0,..., n 1. O inteiro correspondente a esta sequência de bits é: a n 1 2 n 1 + a n 2 2 n 2... + a 0 = n 1 i=0 a i 2 i Este código designa-se por código binário ponderado. Computadores e Programação p.13
Codificação de inteiros O maior número inteiro que é possível representar com um conjunto de n bits é n 1 i=0 2 n = 2 n 1 n bits 2 n números inteiros, incluindo o zero: 0, 1,..., 2 n 1. Computadores e Programação p.14
Conversão decimal/binário A conversão de um número inteiro na base 10 em código binário ponderado é muito fácil. Exemplo: Conversão do decimal 203 para a base 2. Representando o quociente e o resto da divisão inteira pelos operadores div e mod, temos: 203 div 2 =101; 203 mod 2 = 1 = a0; 101 div 2 = 50; 101 mod 2 = 1 = a1; 50 div 2 = 25; 50 mod 2 = 0 = a2; 25 div 2 = 12; 25 mod 2 = 1 = a3; 12 div 2 = 6; 12 mod 2 = 0 = a4; 6 div 2 = 3; 6 mod 2 = 0 = a5; 3 div 2 = 1; 3 mod 2 = 1 = a6; 1 div 2 = 0; 1 mod 2 = 1 = a7; Então 203 10 = 11001011 2. Computadores e Programação p.15
Conversão decimal/binário A conversão inversa (binário decimal) é trivial. Exemplo: 11001011 2 = 1 2 7 + 1 2 6 + 1 2 3 + 1 2 + 1 = 203 10 Computadores e Programação p.16
Notação octal/hexadecimal É comum utilizar-se a notação hexadecimal, (base 16) para exprimir de forma mais compacta números binários. Cada dígito hexadecimal equivale a 4 dígitos binários. Noutra notação, denominada octal, o número é representado na base 8, em que cada dígito octal (0...7) agrupa 3 bits. Em hexadecimal são utilizados os 16 símbolos 0, 1, 2,..., 9, A, B, C, D, E, F. Por exemplo, o número 200 10 pode ser escrito como 11001000 2, C8 16 ou 310 8. Computadores e Programação p.17
Tabela de conversão entre as bases mais usadas Binário 0000 0001 0010 0011 0100 0101 0110 0111 Decimal 0 1 2 3 4 5 6 7 Hexa. 0 1 2 3 4 5 6 7 Binário 1000 1001 1010 1011 1100 1101 1110 1111 Decimal 8 9 10 11 12 13 14 15 Hexa. 8 9 A B C D E F A transcrição de um número inteiro na base 10 para base 2 pode ser facilitada, sobretudo quando se trata de números grandes, fazendo primeiro a transcrição para hexadecimal, e utilizando a tabela acima para transcrever cada dígito hexadecimal na correspondente sequência de 4 algarismos binários. Computadores e Programação p.18
Codificação de números relativos Existem vários códigos que permitem codificar números inteiros relativos (códigos bipolares). O código bipolar mais simples é o código de sinal e valor absoluto: o bit mais significativo representa o sinal os restantes n 1 bits o valor absoluto. Por convenção, o bit de sinal tem o valor 1 quando o número é negativo e o valor 0 quando é positivo. Por exemplo, numa palavra de 8 bits, os números ±19 têm, neste código, a seguinte representação binária: +19 10 = 00010011 19 10 = 10010011 Computadores e Programação p.19
Codificação de números relativos Vantagem deste código: simplicidade. Desvantagens: podem-se representar apenas 2 n 1 números distintos com n bits e não 2 n (o zero tem representação dupla) a adição de números relativos é problemática. Computadores e Programação p.20
Código de complementos de 2 No código de complementos de 2 representam-se os números positivos como no código anterior, e representa-se cada número negativo somando 1 ao complemento do número positivo que lhe corresponde. Um eventual transbordo que ocorra nesta soma é ignorado. Vejamos como representar o número 19 numa palavra de 8 bits usando este código: +19 10 = 00010011 19 10 = 11101100 + 00000001 = 11101101 Regra prática para converter um número binário no respectivo complemento de 2: copiam-se os dígitos, a começar pelo bit menos significativo até encontrar o primeiro 1, que também se copia. A partir daí, substituem-se os 0 s por 1 s e vice-versa. Computadores e Programação p.21
Código de complementos de 2 Vantagens da representação de complementos de 2: O zero tem representação única (verifique!). O bit mais significativo pode ser interpretado como bit de sinal: este bit é zero nos números positivos e 1 nos números negativos. O bit menos significativo determina sempre se um número é par ou ímpar, o bit é zero nos números pares e 1 nos ímpares. O número total de números que é possível representar neste código numa palavra de n bits é 2 n, correspondendo ao intervalo 2 (n 1),...,2 (n 1) 1. Computadores e Programação p.22
Representação de números reais Na base decimal 17.32 10 = 1 10 1 + 7 10 0 + 3 10 1 + 2 10 2 Do mesmo modo, na base 2 teremos 17.32 10 = 1 2 4 + 0 2 3 + 0 2 2 + 0 2 1 + 1 2 0 + + 0 2 1 + 1 2 2 + 0 2 3 + 1 2 4 + 0 2 5 = + 0 2 6 + 0 2 7 + 1 2 8 +... = 10001.01010001... 2 Mas 10001.01010001 2 = 17.31640625 10 17.32 10! E 10001.0101000111101011 2 = 17.3199920654296875 10! Parece não haver representação binária finita de 17.32 10... Computadores e Programação p.23
Representação em vírgula flutuante (IEEE754) Os números reais formam um conjunto denso não é possível representar exactamente um (intervalo) de reais num computador! Representação em vírgula fixa: número fixo de casas decimais, digamos 6. Basta codificar um inteiro (o número sem a vírgula)! Não é uma boa escolha limita a gama dinâmica de valores que se podem representar com um conjunto de n bits. Utiliza-se a notação em vírgula flutuante, semelhante à notação científica: mmmmmm 10 eeee, mmmmmm mantissa eeee expoente Computadores e Programação p.24
Representação em vírgula flutuante (IEEE754) Por exemplo, o número 0.000341237 pode ser escrito de várias formas: 0.00341237 10 1, 0.0341237 10 2,...3.41237 10 4 A última é a forma canónica normalizada (não tem zeros atrás do ponto decimal). A representação em vírgula flutuante é efectuada habitualmente em 32, 64 ou 128 bits (precisão simples, dupla, e quádrupla). Em precisão simples: s eeeeeeee mmmmmmmmmmmmmmmmmmmmmmm Computadores e Programação p.25
Representação em vírgula flutuante (IEEE754) bit 31 bit de sinal bits 30 23 expoente bits 22 0 mantissa Nota: utiliza-se normalização, pelo que se subentende que o primeiro algarismo da mantissa é diferente de zero. Na base 2 este algarismo só pode ser 1, e portanto não se representa. Assim, usando 23 bits a mantissa tem 24 bits efectivos de precisão! O expoente é codificado com um offset de 127, ou seja é preciso subtrair 127 ao número inteiro que representa o expoente para obter o seu valor real. Computadores e Programação p.26
Representação em vírgula flutuante (IEEE754) Os valores reais do expoente com significado variam entre -127 e 127 (0 a 254 sem offset). Reserva-se o padrão eeeeeeee = 11111111 = 255 para representar os infinitos (s = 0, m = 0, + ), (s = 1, m = 0, ). Também existem dois zeros (s = 0, m = 0, 0 + ) e (s = 1, m = 0, 0 ). Os padrões com a mantissa 0 e expoente = 255 não representam números, mas códigos de erro (NAN - not a number, por exemplo divisão por zero). P. bits sinal mants. expo. min max alg. sign. S 32 1 23 8 1.2E-38 3.4E38 6 9 D 64 1 52 11 2.2E-308 1.8E308 15-17 Computadores e Programação p.27
Representação em vírgula flutuante (IEEE754) Numa codificação de 32 bits, não se pode armazenar mais informação do que a permitida pelos 32 bits o número de números reais com representação distinta neste esquema de codificação é = 2 32, tal como para os números inteiros. A interpretação dos bits é diferente, mas o número de possibilidades distintas de codificação é o mesmo. No caso dos números inteiros, a distribuição é uniforme, mas já o mesmo não se passa com a representação em vírgula flutuante! Os números reais representados neste formato não estão uniformemente distribuídos. Computadores e Programação p.28
Representação em vírgula flutuante (IEEE754) De facto, a distribuição é uniforme numa escala logarítmica: existem tantos números (2 24 para uma mantissa de 23 bits, ou seja cerca de 8 milhões) entre 2 3 e 2 2 como entre 2 52 e 2 53. A representação dos números reais em vírgula flutuante não é (em geral) exacta e a aritmética efectuada com esta representação também não! O processo de normalização pode causar sérios erros de arredondamento. Exemplo: matematicamente 1 + x 1 = x, mas em aritmética de vírgula flutuante 1 + x 1 pode resultar num número muito diferente de x. Computadores e Programação p.29