Aritmética de ponto flutuante
Opa pessoal! Depois das apresentações, um post com alguma coisa útil… ou não :P. Vou falar sobre algo em que trabalhei há um tempinho atrás na universidade e que acho muito interessante: o sistema de ponto flutuante. Para alguns esse assunto pode ser bastante massante, mas um conhecimento básico sobre ponto flutuante é de extrema importância para qualquer pessoa que trabalhe de forma séria com informática porque problemas derivados do seu uso eventualmente se tornam grandes armadilhas. Enfim… deixa eu parar com a enrolação :).
Os números de ponto flutuante () são uma tentativa de representar os números reais () nos computadores. Entretanto, dada a finitude inerente aos dispositivos computacionais, há perda de informação — e, portanto, é subconjunto próprio de — de modo que uma das maiores preocupações matemáticas ao se trabalhar com o sistema de ponto flutuante é a falta de fecho aritmético. Isso corresponde a dizer que, para , nem sempre é verdade que . De fato, isso é um problema. Afinal de contas, se o resultado de uma operação não é representável no conjunto de trabalho, a aritmética perde em robustez tornando-se inconsistente e, para todos os fins práticos, inútil.
Uma solução é redefinir os operadores sobre de tal forma a criar o fecho. A idéia é aplicar uma função (arredondamento) aos resultados para fazê-los “caber” no conjunto. Formalmente, seja . Dizemos que é um arredondamento se obedece às seguintes propriedades:
Ao contrário do que esse formalismo sugere, o significado de tais propriedades é bastante simples. A primeira delas estabelece que todos os elementos do conjunto dos números de ponto flutuante são fixados pela função de arredondamento. Ou seja, o arredondamento de um número de ponto flutuante é o próprio número. A segunda garante a preservação da relação de ordem (monoticidade), o que era de se esperar. Em conjunto, essas propriedades implicam no resultado mais importante a respeito da natureza do arredondamento: a característica de máxima qualidade. O que se quer dizer com isso é que , ou seja, entre um número real e o seu ponto flutuante correspondente não existem intermediários pertencentes a .
Tudo bem, mas qual é a utilidade disso no estabelecimento de uma aritmética de ponto flutuante útil e robusta? Dado , seja o operador correspondente em . Nós definimos uma aritmética de ponto flutuante como:
Nesse ponto aparece uma questão de ordem prática bastante relevante. Ora, se eu preciso aplicar a função ao resultado da operação , então de alguma forma eu precisarei representar este resultado na máquina. Mas, não é precisamente esse problema que estamos tentando resolver?! A circularidade é apenas aparente, entretanto. Com efeito, é possível mostrar que, se e estão armazenados em registradores com dígitos de precisão, o valor exato da operação pode ser armazenado em um intermediário com dígitos – para detalhes a respeito da técnica e do porquê de seu funcionamento, recomendo [1]. Procede-se então o arredondamento adaptando o resultado ao registrador ordinário de dígitos.
Agora que nós definimos uma aritmética de ponto flutuante abstrata, é necessário concretizá-la. No contexto, isto significa que nós precisamos definir o comportamento da função , o que pode ser feito de 4 formas diferentes como descrito abaixo.
Round to zero
Este é o método de arredondamento mais simples que existe. Formalmente, a função round to zero é definida como
onde é o que o próprio nome diz. Este arredondamento é o mais facilmente implementável. De fato, se tem precisão , é suficiente descartar os dígitos além da posição . Por causa disso, este método também é conhecido como truncagem.
Round toward minus infinity
Este é um dos modos de arredondamento pertencentes à classe dos direcionados. Um arredondamento direcionado deve resultar no ponto flutuante imediatamente anterior (ou posterior) ao número real correspondente. Formalmente, ele deve satisfazer uma das seguintes propriedades:
Particularmente, o round toward minus infinity obedece a primeira propriedade e é definido por:
Note as semelhanças entre este modo e o round to zero. Apesar de parecerem idênticos, existe uma diferença sutil. Por exemplo, se nós tivermos um sistema de ponto flutuante com 2 dígitos de precisão e tentarmos arredondar -1.234 usando o round to zero, nós obteremos -1.23. Por outro lado, se usarmos o round to minus infinity, o resultado será -1.24. De forma geral, é verdade que .
Round toward plus infinity
O round toward plus infinity é o análogo simétrico do round toward minus infinity. Portanto, este arredondamento satisfaz a segunda das duas propriedades citadas acima e é definido como:
Note uma propriedade interessante dos arredondamentos direcionados: do que foi dito, nós podemos concluir que o intervalo é o menor cujos extremos são números em e contém . Então, o diâmetro deste intervalo é o erro máximo cometido pela função arredondamento. Esta propriedade é usada na Aritmética Intervalar de Precisão Máxima.
Round to nearest
Uma metodologia mais inteligente de arredondamento é considerar o ponto médio do intervalo . Desta forma, se , retorne , caso contrário, se , então retorne . Se , nós temos que decidir o que fazer. Esta decisão cria diferentes variantes do arredondamento. O round to nearest implementa exatamente esse método. Em geral, o erro cometido por este modo é menor que o dos outros.
Bem, por agora é isso :). Desculpe se tudo isso foi maçante. De fato, esta é uma abordagem muito teórica para um problema muito prático, mas eu gosto de alguma teoria antes das questões práticas. Isso ajuda a dar fundamentação a possíveis soluções. Em algum ponto no futuro irei escrever sobre o erro de arredondamento considerando o padrão de ponto flutuante IEEE 754 de um ponto de vista prático. Então, até a próxima… :)
Introducing myself…
Hi people!
My name is Rafael Barreto and I am an undergraduate in Computer Engineering at Federal University of Pernambuco (UFPE) in Brazil. I always wanted to have a blog to share stuff I find interesting, but I guess I do not have the discipline for it :P. Well, this is a try… let’s see if I can stand with it.
My main focus here is technical stuff, especially related to computing and math. However, I like literature and music a lot. So, it’s possible these themes appear here eventually.
I will try to keep it in english (despite I cannot guarantee this). Mainly because it makes the blog much more accessible and because I really need to practice my writing :P.
That’s it… enough of presentation… =P