Baixe o app para aproveitar ainda mais
Prévia do material em texto
Josué Abranti Métodos computacionais Aritmética de Ponto Flutuante Brasil Porto Alegre 05 de Abril de 2020 Josué Abranti Métodos computacionais Aritmética de Ponto Flutuante Trabalho acadêmico apresentado à disci- plina de Métodos Computacionais da insti- tuição Pontíficia Universidade Católica do Rio Grande do Sul como parte dos requisi- tos necessários para obtenção do título de Engenheiro de Computação. Pontifícia Universidade Católica do Rio Grande do Sul - PUCRS Escola Politécnica Engenharia de Computação Brasil Porto Alegre 05 de Abril de 2020 Josué Abranti Métodos computacionais Aritmética de Ponto Flutuante/ Josué Abranti. – Brasil, Porto Alegre 05 de Abril de 2020- Pontifícia Universidade Católica do Rio Grande do Sul - PUCRS Escola Politécnica Engenharia de Computação, Porto Alegre 05 de Abril de 2020. 1. Métodos Computacionais. 2. Computação Científica. I. Beatriz Franciosi. II. Pontifícia Universidade Católica do Rio Grande do Sul. “ A Matemática apresenta invenções tão sutis que poderão servir não só para satisfazer os curiosos como, também para auxiliar as artes e poupar trabalho aos homens ” (René Descartes, Século 17) Lista de ilustrações Figura 1 – Régua . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9 Figura 2 – Definição matemática do sistema de ponto flutuante . . . . . . . . . . . 11 Figura 3 – Diferença dos valores em número real para a representação em ponto flutuante . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13 Figura 4 – Região de overflow e underflow . . . . . . . . . . . . . . . . . . . . . . 15 Sumário Introdução . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7 1 ALGARISMOS SIGNIFICATIVOS . . . . . . . . . . . . . . . . . . . 9 2 ARITMÉTICA DE PONTO FLUTUANTE . . . . . . . . . . . . . . 11 3 VISÃO GERAL DA ARITMÉTICA DE PONTO FLUTUANTE . . . 13 4 OVERFLOW E UNDERFLOW . . . . . . . . . . . . . . . . . . . . . 15 5 ADIÇÃO E SUBTRAÇÃO . . . . . . . . . . . . . . . . . . . . . . . . 17 6 MULTIPLICAÇÃO E DIVISÃO . . . . . . . . . . . . . . . . . . . . . 19 Introdução Entra 1970 e 1980 um grupo formado por cientistas e engenheiros de de diferentes empresas de computação realizou um trabalho intenso na tentativa de encontrar um padrão de representação dos números, que deveria ser adotado por todas as indústrias na construção de seus computadores. A necessidade desta padronização tinha como principal objetivo de uniformizar os resultados obtidos por um mesmo programa computacional executado em diferentes máquinas. Esta discussão teve início em 1976, e este grupo de trabalho ficou conhecido como IEEEp754, pois foir organizado pleo Institute for Electrical and Eletronics Engineers (IEEE). Entre os fabricantes estavam Apple, Zilog, DEC, Intel, Hewlett-Packard, Motorola e National Semicondutor. O professor William Kahan liderava o grupo de cientistas e pelo trabalho desenvolvido neste projeto, recebeu o prêmio Turing Prize de 1989. Este projeto tinha como metas principais: - Especificar como representar os números em precisão simples e dupla. - Padronizar o arredondamento nas operações neste sistema. - Estabelecer critérios para padronizar situações como divisão por zero, operações envolvendo infinito. 9 1 Algarismos significativos Algarismos significativos de um número são aqueles que podem ser usados com confiança e geralmente corresponde ao número de algarismos corretos mais um estimado, também chamado de duvidoso, e esse algarismo duvidoso carrega com ele uma incerteza e é nela que mora o erro. Por exemplo, na marcação de uma régua, quantos centímetros podemos dizer que ela está medindo? Figura 1 – Régua Bom, podemos afirmar com certeza que ela está medindo mais que 2,2 e menos que 2,3 cm. Mas existe um intervalo entre esses números que nós não identificamos com certeza absoluta. Podemos colocar esse número mais perto do 2,2 cm ou mais perto do 2,3 cm. Mas qual valor esta certo? Não podemos afirmar nada. Então, temos uma incerteza. E isso está dependendo do observador ou do equipamento que você está usando para tirar essa medida. Devido a este problema encontrado em representações computacionais usa-se a aritmética de ponto flutuante, uma vez dependendo do uso a representação inteira pode ser utilizada, porém em outros casos se faz necessário conhecer qual a precisão utilizada. 11 2 Aritmética de Ponto Flutuante Embora números inteiros forneçam uma representação exata para valores numéricos, eles têm uma grande desvantagem: a inabilidade para representar valores fracionários. Aritmética em ponto flutuante resolve este problema. Programadores são advertidos da perda de velocidade associada com aritmética de ponto flutuante; contudo, os benefícios obtidos com o uso de ponto flutuante superam esta desvantagem. Um sistema de ponto flutuante F ⊂ R é um subconjunto dos números reais cujos elementos tem a forma: Figura 2 – Definição matemática do sistema de ponto flutuante A aritmética de ponto flutuante F é caracterizada por quatro números inteiros: • base β (binária, decimal, hexadecimal e etc...); • precisão t (número de algarismos da mantissa); • limites do expoente e (emin≤ e ≤ emax); Portanto a definição de F é dada por F(β, t, emin, emax). A mantissa é fracionária nesta representação (<1). A fim de assegurar representação única para cada y ∈ F, faz−seumanormalizaçãonosistemadeformaque0d1 6= 0paray 6= 0. 13 3 Visão Geral da Aritmética de Ponto Flutu- ante Um grande problema com a aritmética de ponto flutuante é que ela não segue as regras padrões da álgebra. Números inteiros também não seguem as regras padrões da álgebra, porque a representação deles é feita com números finitos de bits. Não se pode representar nenhum valor inteiro acima do ’valor máximo’ ou abaixo do ’valor mínimo’ suportado por determinada representação binária. Ponto flutuante, não só sofre deste mesmo problema, como também de outro: números inteiros são um subconjunto dos números reais. Sendo assim, os valores de ponto flutuante representam o mesmo conjunto de inteiros infinitos. Contudo, há um número infinito de valores entre quaisquer dois números reais; assim o problema é infinitamente pior. Entretanto, da mesma forma que foram limitados os valores na faixa entre máximos e mínimos, não se pode representar todos os valores entre essa faixa. Figura 3 – Diferença dos valores em número real para a representação em ponto flutuante Para representar números reais, o mais comum é o uso da notação científica, usando a maior parte dos dígitos para representar a mantissa e a menor parte para representar o expoente. Assim, estes números de ponto flutuante podem somente ser representados através de um número específico de dígitos significativos. Isto tem um grande impacto na operação com aritmética de ponto flutuante É fácil ver o impacto de utilizar precisão limitada na aritmética de ponto flutuante: adotando um formato simplificado de ponto flutuante decimal, por exemplo, com uma mantissa com três dígitos significativos e um expoente decimal com dois dígitos, sendo a mantissa e o expoente com valores sinalizados 15 4 Overflow e Underflow O conjunto de números de números reais é infinito, entretanto, a sua representação em um sistema de ponto flutuante é limitada, pois é um sistema finito, o que não a representação exata da totalidade dos números reais. Essa limitação tem duas origens: • a faixa dos expoentes é limitada (emin ≤ e ≤emin); • a mantissa pode representar um número finito de números (β−1 ≤ m ≤ −β−t); A primeira limitação leva aos fenômenos chamados de “overflow” e “underflow”. A Segunda leva aos erros de arredondamentos, que será visto na próxima seção. Sempre que uma operação aritmética produz um número com expoente superior ao expoente máximo, tem-se o fenômeno de “overflow”. De forma similar, operações que resultem em expoente inferior ao expoente mínimo tem-se o fenômeno de “underflow”. No caso do exemplo dado, pode-se observar qualas regiões que ocorrem o overflow e o underflow. Neste caso, considera-se a parte positiva e negativa da aritmética do exemplo. Figura 4 – Região de overflow e underflow Observe que, se o expoente for maior que 3 ou menor que -1, não tem-se represen- tação no conjunto formado pela aritmética de ponto flutuante. No primeiro caso, tem-se o overflow, no segundo caso, tem-se o underflow. Quando da ocorrência de overflow ou underflow, a máquina realiza alguma ação. Cada máquina responde de alguma forma. As principais ações são: Overflow a) Pára o cálculo Overflowb) Retorna um número que representa o infinito da máquina (IEEE) 16 Capítulo 4. Overflow e Underflow Underflow a) Pára o cálculo b) Arredonda para zero c) Arredonda para um número subnormal As duas maneiras que a máquina trata o overflow possuem aspectos indesejáveis. No primeiro caso não possui resposta. No segundo caso também não é muito útil, exceto para interpretações físicas ou aplicações específicas, pois não apresenta uma resposta numérica. No caso do underflow, o primeiro caso é indesejado. Os segundo e terceiro caso resulta em uma resposta útil, mas existe o perigo de numa operação seguinte surgir um overflow. Deve-se procurar evitar overflow e underflow em implementação computacionais. Uma maneira prática de evitar o overflow é o escalonamento, que pode também evitar o underflow. Exemplo: x = √ a2 + b2 Suponha uma máquina com 10 dígitos decimais com expoentes [-99,99] a = b = 1060 a2 e b2 ambos estão em overflow e a computação pode ser parada, mesmo que o resultado seja √ 2×1060 e seja representável na aritmética de ponto flutuante. Similarmente: a = b = 10−60 Pode-se evitar o overflow, utilizando um escalonamento: s = |a| + |b| c = s √( a s )2 + ( b s )2 Esta formulação também evita o underflow. 17 5 Adição e subtração O problema que enfrentamos é que, além dos bits significativos, temos o escalo- namento (ou o “deslocamento” do ponto). Na adição precisamos que ambos os valores tenham a mesma escala para poder adicioná-los. Um exemplo, em decimal, é a tentativa de adicionar 1.0×100 ao valor 1.0×102. Não podemos, simplesmente, somar 1.0 com 1.0! Temos que tornar as escalas (100 e 102) iguais e, para isso, adaptamos o menor valor: 1.0× 102 + 0.01× 102 = 1.01× 100 Aqui, 1.0×100 foi transformado em 0.01×102. O motivo de adequarmos o menor valor é que os bits do menor valor serão deslocados para a direita e a adição tenderá a obter uma soma normalizada. Troque agora o valor normalizado por um valor inteiro binário (com o bit 23, implícito, setado) e a escala na base 2, ao invés de 10. Existe um detalhe interessante: Se a diferença entre os expoentes EaeEbformaiorque24, significaqueomenorvalorpodeserseguramentedesconsideradonaadição.Omotivo, óbvio, équeeledeveráserdeslocado24bitsparaadireita, fazendocomquetodososseusbitssignificativosıdesapareçam.Assim, aadiçãosóéfeitaseEa− Eb < 24ondeEa > Eb. A subtração segue as mesmas regras, mas a ordem com a qual os operandos aparecem é importante. 19 6 Multiplicação e divisão Diferente da adição (e da subtração), a multiplicação não precisa sofrer adequações das frações. Isso fica claro quando você percebe que basta somar os dois expoentes de mesma base para obter a escala correta e, as frações, só precisam ser multiplicadas: (fa · 2Ea) · (fb · 2Eb) = (fa · fb) · 2Ea+Eb O detalhe é que, ao obtermos a fração com o bit implícito, teremos um valor de 24 bits de tamanho que, ao multiplicar por outro valor de 24 bits de tamanho nos dará um valor de 48 bits de tamanho. Considere o caso de multiplicarmos 1.0 por ele mesmo. Esse valor é codificado, em hexadecimal, como 0x800000. Depois da multiplicação obtemos 0x400000000000. Não é óbvio, mas o resultado encontra-se 23 bits deslocado para a esquerda, ou seja, justamente os 23 bits da parte fracionária dos argumentos originais! A resposta é justamente [(a · b) shr 23] · 2Ea + Eb, onde a e b são os valores inteiros de 24 bits com o bit implícito! A divisão, é claro, segue o sentido inverso. os bits significativos devem ser divididos e os expoentes subtraídos, mas diferente da multiplicação, o dividendo deve ser deslocado 23 bits para a esquerda antes que a divisão possa ser feita. Novamente, vamos tentar dividir 1.0 por ele mesmo. . . Se dividirmos 0x800000 por ele mesmo obteremos o quociente 1. Mas 1 é apenas o bit 0 da fração, ou seja, 2−23. Mas, se deslocarmos a para esquerda em 23 bits, teremos 0x4000000000000x800000 = 0x800000. Assim, a divisão binária fica a shl 23 b · 2Ea−Eb . Claro que temos que considerar o caso espacial onde labelb = 0. Atenção que a renormalização também pode ser necessária depois de multiplicações e divisões. Tomemos o caso onde todos os bits significativos estejam setados e E=0. Se quisermos elevar esse valor ao quadrado, neste caso, a será 0xffffff e obteremos 0xfffffe000001. Ao deslocarmos 23 bits para a direita teremos 0x1fffffc, que tem 25 bits de tamanho! Isso deve ser deslocado em 1 bit para a direita e o valor de E incrementado. Como os dois valores originais tm expoente zerado, o expoente final deveria ser zerado também Ea + Eb = 0 + 0 = 0, mas a renormalização nos deu um expoente unitário, sendo fácil perceber que a parte fracionária é resultante do shift para a direita do valor que expus anteriormente. Na divisão algo similar pode acontecer, mas no sentido contrário. Folha de rosto Epígrafe Lista de ilustrações Sumário Introdução Algarismos significativos Aritmética de Ponto Flutuante Visão Geral da Aritmética de Ponto Flutuante Overflow e Underflow Adição e subtração Multiplicação e divisão
Compartilhar