Vírgula flutuante
Esta página cita fontes, mas que não cobrem todo o conteúdo. |
Larguras de bit em arquitetura de computadores |
---|
Tamanho da palavra (em bits) |
Tipos primitivos de variáveis |
Unidades de informação |
Vírgula flutuante (original em alemão Gleitkomma ou Fließkomma) ou ponto flutuante (do inglês floating point) é um formato de representação digital de números racionais, que é usada nos computadores.
História
[editar | editar código-fonte]Vários estudiosos contribuíram para a história da virgula flutuante, dentre eles, Leonardo Torres y Quevedo, que, em 1914 projetou uma versão eletromecânica da Máquina Analítica de Charles Babbage, e nela incluiu a aritmética de ponto flutuante.[1] Já Konrad Zuse de Berlim, em 1938, completou o Z1, o primeiro binário programável em um computador mecânico.[2] A representação que ele utiliza é de número de ponto flutuante binário de 24 bits com um expoente assinado de 7 bits, um significando (incluindo um bit implícito) e um bit de sinal.[3] O binário Z3 foi concluindo em 1941 e tem representações para infinitos positivos e negativos; em particular, ele implementa operações definidas com infinito, como 1/ ∞ = 0 ,e para em operações indefinidas, como 0 x ∞.
Konrad Zuse também propôs o Z3, mas não completou. A aritmética de ponto flutuante cuidadosamente arredondada que incluem ± ∞ e representações NaN, antecipando recursos do IEEE que foi padrão por quatro décadas.[4] Por outro lado, von Neumann recomendou contra números de ponto flutuante para a máquina IAS 1951, argumentando que a aritmética de ponto fixo é preferível.[4]
O primeiro computador comercial com hardware de ponto flutuante foi o Z4 da Zuse. Foi projetado em 1942-1945. Em 1946, Bell Laboratories introduziu o Mark V, que implementou números de ponto flutuante decimal.[5]
O Pilot ACE, um dos primeiros computadores construídos no Reino Unido, tem aritmética de ponto flutuante binário, e tornou-se operacional em 1950 no National Physical Laboratory. Após sua produção, trinta e três dele foram vendidos comercialmente como o Inglês Elétrico DEUCE. A aritmética nesses computadores era implementada em software, mas com uma taxa de tempo de um megahertz, a velocidade do ponto flutuante e do ponto fixo nas operações dessa máquina foram inicialmente mais rápidas do que as de muitos computadores concorrentes
O IBM 704, foi um computador desenvolvido para cálculos de larga escala, primordialmente para fins comerciais. Começou a ser produzido em massa em 1954. Décadas depois, o hardware de ponto flutuante era tipicamente um recurso opcional e os computadores que os possuíam foram chamados de "computadores científicos", ou ter capacidade de "computação científica" (SC). Somente a partir do lançamento do Intel i486, em 1989, que os computadores pessoais de uso geral tiveram capacidade de ponto flutuante em hardware como um recurso padrão.
A série UNIVAC 1100/2200, introduzida em 1962, suportava duas representações de ponto flutuante:
- Precisão simples: 36 bits, organizado como um sinal de 1 bit, um expoente de 8 bits e um significando de 27 bits.
- Precisão dupla: 72 bits, organizado como um sinal de 1 bit, um expoente de 11 bits e um significando de 60 bits.
O IBM 7094, que também foi lançado em 1962, suporta representações de precisão simples e dupla, mas sem relação com às representações da UNIVAC. Em 1964, a IBM introduziu as representações de ponto flutuante hexadecimal em seu System / 360, unidades centrais de processamento, e elas ainda estão disponíveis para uso em sistemas z / Architecture modernos. No entanto, em 1998, a IBM incluiu aritmética de ponto flutuante binário compatível com IEEE em seus mainframes, gabinete principal que alojava a unidade central de processamento nos primeiros computadores. Em 2005, a IBM também adicionou IEEE-aritmética de ponto flutuante decimal compatível.
Inicialmente, os computadores usaram muitas representações diferentes para números de ponto flutuante. A falta de padronização no nível de mainframe era um problema contínuo no início dos anos 1970 para aqueles que escreviam e mantinham código-fonte de nível superior. Esses padrões de ponto flutuante do fabricante diferiam nos tamanhos das palavras, nas representações e no comportamento de arredondamento e precisão geral das operações.
A compatibilidade de ponto flutuante em vários sistemas de computação precisava desesperadamente de padronização no início de 1980, levando à criação do padrão IEEE 754, uma vez que a palavra de 32 bits (ou 64 bits) tinha se tornado comum. Este padrão foi significativamente baseado em uma proposta da Intel, que estava projetando o i8087 coprocessador numérico. A Motorola, que estava projetando o 68000 na mesma época, também deu uma contribuição significativa.
Em 1989, o matemático e cientista da computação William Kahan foi homenageado com o Prêmio Turing por ser o principal arquiteto por trás dessa proposta. Ele foi auxiliado por seu aluno (Jerome Coonen) e um professor visitante (Harold Stone).[6]
Entre as inovações do x86 estão:
- Uma representação de ponto flutuante precisamente especificada no nível da string, cadeia de caracteres, de bits de modo que todos os computadores compatíveis interpretarem padrões de bits da mesma maneira. Isso torna possível transferir com precisão e eficiência do ponto flutuante números de um computador para outro (após considerar a extremidade).
- Um comportamento precisamente especificado para as operações aritméticas: um resultado deve ser produzido como se infinitamente aritmética precisa foi usada para produzir um valor que é então arredondado de acordo com regras específicas. Isso significa que um programa de computador compatível sempre produziria o mesmo resultado quando dado uma entrada particular, mitigando assim a reputação quase mística que a computação de ponto flutuante desenvolveu para seu até então comportamento aparentemente não determinístico.
- A capacidade de condições excepcionais (estouro, divisão por zero, etc.) de se propagar por meio de um cálculo em um de maneira benigna e, em seguida, gerenciado pelo software de maneira controlada.
Generalidades
[editar | editar código-fonte]Ao falar em números reais a visualização vinda à cabeça é:
No entanto, essa representação custa caro, em termos de processamento e armazenamento ao computador havendo a necessidade de utilizar uma outra maneira que favoreça tais tarefas. Para trabalhar com a parte fracionária de forma satisfatória, usa-se a representação por vírgula flutuante.
Essa representação baseia-se no deslocamento da vírgula de forma que se obtenha um número menor ou próximo de 1. Esse deslocamento é feito por meio de notação científica. Esclarecendo: o número 25,456 em notação corresponde ao 0,25456 x 102.
O exemplo acima tinha como base a decimal, no entanto o computador trabalha com a base 2 (binários – 0 e 1). Então um número binário 11,011 em notação corresponde ao 0,11011 x 22. Esse processo de transcrever um número em notação científica recebe o nome de normalização, portanto 0,11011 x 22 está normalizado.
De forma geral, representa-se um número em vírgula flutuante da seguinte forma:
- +- M X B+-e
Onde:
Esquematicamente tem-se[7]:
Desta forma é possível cobrir um largo espectro de números, maximizando o número de bits significativos e consequentemente a precisão da aproximação. Esta forma de representação foi criada por Konrad Zuse para os seus computadores Z1 (1937) e Z3 (1941), batizada, então, de Gleitkommazahl (literalmente número com vírgula escorregante).[carece de fontes]
O número de bits alocados para representar a mantissa e o expoente depende da norma utilizada.
Para obter o número em vírgula flutuante converte-se o número para a base na qual será armazenado, normaliza-o e por fim separa-se mantissa, expoente e sinais.
Exemplo[8]:
Assumindo:
- 1 bit para o sinal do número
- 1 bit para o sinal do expoente
- 4 bits para o expoente
- 10 bits para a mantissa
Represente o número 5,7510 em vírgula flutuante. O número em questão encontra-se na base 10, portanto é preciso convertê-lo para binário (base 2), base entendida pelo computador. 5,7510 => 101,112
Normalizando tem-se: 0,10111 x 23
Separando sinais, mantissa e expoente tem-se:
- Sinal do número: (+) 0
- Sinal do expoente: (+) 0
- Expoente: 011 (3)
- Mantissa: 10111
Portanto tem-se: 00001100000101112
A maioria dos sistemas que operam com vírgula flutuante utilizam representações definidas na norma IEEE 754.
O padrão IEEE para aritmética de vírgula flutuante (IEEE 754) é o padrão mais amplamente utilizado, e é seguido por muitos CPU e melhorias FPU. A norma define formatos para representar números de vírgula flutuante (incluindo zero) e os valores não normalizados, bem como os valores especiais infinito e NaN, com um conjunto de operações de vírgula flutuante que trabalham com esses valores. Também especifica quatro modos de arredondamento e cinco exceções (inclusive quando essas exceções ocorrem é o que acontece nesses momentos). A Norma IEEE 754-2008 define os formatos adequados para representar números em vírgula flutuante de precisão simples (32 bits) e de precisão dupla (64 bits). O título completo da norma é o padrão IEEE para Aritmética Binária de Vírgula Flutuante (ANSI / IEEE Std 754-1985), e também é conhecido pelo IEC 60559:1989, Binary floating-point arithmetic for microprocessor systems (originalmente o número de referência era IEC 559:1989).[9][10]
O formato de vírgula flutuante de precisão simples (32 bits) consiste num bit de sinal (s), 8 bits de expoente (e) e uma mantissa de 23 bits (m). O bit de sinal (s) é 0 (zero) para números positivos e 1 para números negativos. O campo de expoente (e) corresponde à soma de 127 com o expoente de base 2 do número representado. O campo de mantissa (m) corresponde à parte fracionária da mantissa do número representado. Considera-se sempre a mantissa normalizada entre 1 e 2. Desta forma a sua parte inteira é sempre apenas um bit igual a 1 (um) que não é necessário representar.
v = S × M × 2E
Onde:
S = 1 − 2 × s
M = 1.m = 1 + m × 2−23
E = e − 127
sinal (1 bit) | expoente (8 bits) | mantissa (23 bits) | ||||||||||||||||||||||||||||||
┃ | ┌────────────────────┐ | ┌─────────────────────────────────────────────────────────────────┐ | ||||||||||||||||||||||||||||||
0 | 0 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | |
31 | 30 | 23 | 22 | 0 |
Números representáveis, conversão e arredondamento
[editar | editar código-fonte]Por sua natureza, todos os números expressos em formato de ponto flutuante são números racionais com uma expansão terminante na base relevante (por exemplo, uma expansão decimal terminante na base-10, ou uma expansão binária terminante na base-2). Números irracionais, como π ou √2, ou números racionais não terminativos, devem ser aproximados. O número de dígitos (ou bits) de precisão também limita o conjunto de números racionais que podem ser representados exatamente. Por exemplo, o decimal número 123456789 não pode ser exatamente representado se apenas oito dígitos decimais de precisão estiverem disponíveis (seria arredondado para 123456790 ou 123456780 quando o dígito 0 mais certo não está explicitamente representado), o mesmo se aplica a dígitos não terminativos (0,5 a ser arredondado para .55555555 ou .5555556).
Modos de arredondamento
[editar | editar código-fonte]Os modos de arredondamento são usados quando o resultado exato de uma operação de ponto flutuante (ou uma conversão para formato de ponto flutuante) precisaria de mais dígitos do que contém. O IEEE 754 necessita de um arredondamento correto: ou seja, o resultado arredondado é como se a aritmética infinitamente precisa fosse usada para calcular o valor e, em seguida, arredondada (embora na implementação apenas três bits extras são necessários para garantir isso). Existem alguns esquemas de arredondamento diferentes (ou modos de arredondamento). Historicamente, o truncamento era a abordagem mais comum. Desde a introdução do IEEE 754, o método padrão (arredondado para o número mais próximo, vinculado ao mesmo, ou arredondamento direcionados, também denominado de Arredondamento de Banker) é mais comumente usado. Este método contorna o resultado ideal (infinitamente preciso) de uma operação aritmética ao valor representável mais próximo, e dá essa representação como resultado. No caso de um empate, o valor resultante e terminado em um dígito uniforme é escolhido. A norma IEEE 754 requer o mesmo arredondamento a ser aplicado a todas as operações algébricas fundamentais, incluindo raiz quadrada e conversões, quando há um resultado numérico (não-NaN). Isso significa que os resultados das operações do IEEE 754 são completamente determinados em todos os trechos do resultado, exceto na representação das NaNs. (funções de "Biblioteca", como cosseno e log, não são obrigatórias).
Algumas opções alternativas de arredondamento também estão disponíveis. O IEEE 754 especifica os seguintes modos de arredondamento:
arredondado para o número mais próximo, onde os laços giram em torno do dígito mais próximo mesmo na posição necessária (o padrão e de longe o modo mais comum)
arredondado para o mais próximo, onde os laços giram em volta de zero (opcional para ponto flutuante binário e comumente usado em decimal)
arredondado para cima (em direção a +∞; resultados negativos, portanto, rodada em direção a zero)
arredondado para baixo (em direção a −∞; resultados negativos, portanto, rodada longe de zero)
arredondamento em direção a zero (truncamento; é semelhante ao comportamento comum de conversões flutuantes para inteiros, que convertem −3,9 para −3 e 3,9 para 3)
Os modos alternativos são úteis quando a quantidade de erro que está sendo introduzida deve ser limitada. As aplicações que requerem um erro limitado são ponto flutuante de várias precisões e aritmética de intervalo. Os modos de arredondamento alternativos também são úteis no diagnóstico de instabilidade numérica: se os resultados de uma sub-rotina variam substancialmente entre arredondamento para + e − infinito, então é susceptível que ocorra um fator numericamente instável e afetado por erro de arredondamento.[12]
Propriedades
[editar | editar código-fonte]Esta aritmética tem duas diferenças fundamentais: ela não é, necessariamente, nem associativa nem distributiva:
.
Ou seja, a ordem em que você estiver executando operações de ponto flutuante pode influenciar o resultado. Isto é importante para a análise numérica, uma vez que duas fórmulas matematicamente equivalentes podem ter resultados e precisões diferentes. Por exemplo, na maioria das aplicações de ponto flutuante, 1,0 + (10100 + -10100) resulta em 1,0, enquanto que (1,0 + 10100) + -10100 dá 0,0[carece de fontes]
Problemas
[editar | editar código-fonte]Em geral, o conjunto de números representáveis pela notação de ponto flutuante é semelhante o suficiente ao conjunto dos números reais para a maior parte das aplicações, o que no entanto frequentemente leva programadores a desconsiderar a importância da análise numérica adequada sobre os resultados obtidos. Há muitas inconsistências entre o comportamento dos números de ponto flutuante em base 2 (binário) e os números reais, mesmo em casos muito simples (como a fração decimal 0,1, que por em binário ser uma dízima periódica, não pode ser expressa de maneira exata por qualquer representação binária finita). As principais causas de erro com uso de ponto flutuante são:
- Arredondamento de valores (por exemplo, 0,1);
- Arredondamento de operações aritméticas (por exemplo, 0.1 + 0.2 = 0.30000000000000004[13]);
- Absorção de valores de diferentes níveis de magnitude (por exemplo, 1e8f + 1 - 1e8f = 0[14]);
- Cancelamento (por exemplo, a subtração de dois números muito próximos);
- Overflow, ou transbordamento (com relatórios de resultado infinito);
- Underflow (devolve um 0, ou o número subnormal, menor do que o menor permitido);
- Operação impossível (por exemplo, raiz quadrada de um números negativos resultando em NaN - Not a Number);
- Necessidade de deslocamento dinâmico do expoente.[15]
A notação de ponto flutuante é particularmente adequada quando se almeja uma maior amplitude do domínio representável em detrimento da constância da precisão, cenário frequente em aplicações científicas e de engenharia. Instituições financeiras, porém, frequentemente dão preferência à notação de ponto fixo almejando uma precisão constante.
Alternativas
[editar | editar código-fonte]A representação de ponto flutuante é de longe a maneira mais comum de representar em computadores uma aproximação de números reais. No entanto, existem alternativas:
- A representação de ponto fixo usa operações de hardware controladas por uma implementação de software de uma convenção específica sobre a localização do ponto binário ou decimal, por exemplo, 6 bits ou dígitos da direita. O hardware para operar essas representações é menos caro do que o ponto flutuante e também pode ser usado para realizar operações normais de inteiros. O ponto fixo binário é frequentemente usado em aplicativos de propósito especial em processadores incorporados que só podem fazer aritmética de inteiros, mas o ponto fixo decimal é comum em aplicativos comerciais.
- Os sistemas de números logarítmicos (LNSs) retrata um número real pelo logaritmo de seu valor absoluto e um bit de sinal. A distribuição de valor é semelhante ao ponto flutuante, mas a curva de valor para representação ( ou seja, o gráfico da função logaritmo) é suave (exceto em 0). Ao contrário da aritmética de ponto flutuante, em um sistema de número logarítmico, a multiplicação, a divisão e a exponenciação são simples de implementar, mas a adição e a subtração são mais complexas. A aritmética de índice de nível (simétrico ) (LI e SLI) de Charles Clenshaw, Frank Olver e Peter Turner é um esquema baseado em uma representação logarítmica generalizada.
- Representação cônica de ponto flutuante, que não parece ser usada na prática.
- Onde maior precisão é desejada, aritmética de ponto flutuante pode ser implementada (normalmente em software) com significandos de comprimento variável (e às vezes expoentes) que são dimensionados dependendo da necessidade real e dependendo de como o cálculo prossegue. Isso é chamado de aritmética de ponto flutuante de precisão arbitrária.
- As expansões de ponto flutuante são outra maneira de obter uma maior precisão, beneficiando-se do hardware de ponto flutuante: um número é representado como uma soma não avaliada de vários números de ponto flutuante. Um exemplo é a aritmética double-double, às vezes usada para o tipo C long double .
- Alguns números racionais simples ( por exemplo, 1/3 e 1/10) não podem ser representados exatamente em ponto flutuante binário, não importa qual seja a precisão. Usar uma raiz diferente permite representar alguns deles ( por exemplo, 1/10 em ponto flutuante decimal), mas as possibilidades permanecem limitadas. Os pacotes de software que realizam aritmética racional representam números como frações com numerador e denominador inteiros e, portanto, podem representar qualquer número racional com exatidão. Esses pacotes geralmente precisam usar aritmética "bignum " para os inteiros individuais.
- A aritmética de intervalo permite representar números como intervalos e obter limites garantidos nos resultados. É frequentemente baseado em outras aritméticas, em particular ponto flutuante.
- Sistemas de álgebra computacional, como Mathematica, Maxima e Maple, constantemente podem lidar com números irracionais como π ou de forma completamente "formal", sem lidar com uma codificação específica do significando. Esse programa pode avaliar expressões como "" exatamente, porque está programado para processar a matemática subjacente diretamente, no lugar de usar valores aproximados para cada cálculo intermediário.
Exemplos
[editar | editar código-fonte]A fração decimal:
0,125
é representada por: 1/10 + 2/100 + 5/1000. Da mesma forma, a fração binária:
0,001
tem valor: 0/2 + 0/4 + 1/8. Os dois valores são idênticos, sendo o primeiro escrito na base 10 e o segundo na base 2.
Valor | S × M × 2E | s | m | e | IEEE 754 - Single Precision |
---|---|---|---|---|---|
1 | 1 × 1 × 20 | 0 | 0x00 | 127 | 0 0111 1111 000 0000 0000 0000 0000 0000 |
-1 | -1 × 1 × 20 | 1 | 0x00 | 127 | 1 0111 1111 000 0000 0000 0000 0000 0000 |
0,5 | 1 × 1 × 2−1 | 0 | 0x00 | 126 | 0 0111 1110 000 0000 0000 0000 0000 0000 |
-0,5 | -1 × 1 × 2−1 | 1 | 0x00 | 126 | 1 0111 1110 000 0000 0000 0000 0000 0000 |
0,15625 | 1 × 1,25 × 2−3 | 0 | 0x200000 | 124 | 0 0111 1100 010 0000 0000 0000 0000 0000 |
Tabela com exemplos de números reais de três dígitos significativos e sua representação em notação científica:
Número real | Notação científica |
---|---|
0.000000000000000438 | 4.38× 10−16 |
0.000000438 | 4.38× 10−7 |
0.00438 | 4.38× 10−3 |
0.438 | 4.38× 10−1 |
4.38 | 4.38× 100 |
43.8 | 4.38× 101 |
4380.0 | 4.38× 103 |
43800000.0 | 4.38× 107 |
43800000000000000.0 | 4.38× 1016 |
Valores especiais
[editar | editar código-fonte]As notações com os bits do campo expoente (e) todos a um ou todos a zero são reservadas para valores especiais. O zero é representado com e=0 e m=0. Outros valores de m com e=0 indicam números não normalizados. Nestas casos considera-se a mantissa entre 0 e 1.
IEEE 754 - Single Precision | Valor | ||||
---|---|---|---|---|---|
s | e | m | |||
0 | 0000 0000 | 000 0000 0000 0000 0000 0000 | +0 | Zero | |
1 | 0000 0000 | 000 0000 0000 0000 0000 0000 | -0 | ||
0 | 1111 1111 | 000 0000 0000 0000 0000 0000 | +Inf | Infinito Positivo | |
1 | 1111 1111 | 000 0000 0000 0000 0000 0000 | -Inf | Infinito Negativo | |
0 | 1111 1111 | 010 0000 0000 0000 0000 0000 | +NaN | Not a Number | |
1 | 1111 1111 | 010 0000 0000 0000 0000 0000 | -NaN |
Operações aritméticas
[editar | editar código-fonte]As operações em pontos flutuantes são encontradas normalmente em sistemas que operam em uma grande faixa, de número muito grandes ou muito pequenos, que exige tempo de processamento rápido. Um número, em geral, é representado para um número fixo de dígitos significativos, e escalado usando um expoente em alguma base fixa. Nos sistemas digitais, a base utilizada é a base binária. Desde a década de 1990, a representação mais usada é a definida pelo padrão IEE 754.[17]
Adição e Subtração
[editar | editar código-fonte]Para realizar as operações de adição e subtração é necessário seguir alguns passos, para isso consideramos a soma ou subtração entre dois números, X e Y:[18]
Passo 1 - Escolher o número com menor expoente entre X e Y e deslocar sua mantissa para a direita um número de dígitos igual à diferença absoluta entre os respectivos expoentes;
Passo 2 - Colocar o expoente do resultado igual ao maior expoente entre X e Y;
Passo 3 - Executar a adição ou subtração das mantissas e determinar o sinal do resultado;
Passo 4 - Normalizar o valor do resultado, se necessário;
Passo 5 Arredondar o valor do resultado, se necessário;
Passo 6 - Verificar se houve overflow/underflow.
Exemplo
Dados os números abaixo, primeiro é necessário representá-los com o mesmo expoente:
(Passo 1 e 2)
Com isso, realiza-se a operação:
( Passo 3 e 4)
O resultado verdadeiro é igual a: .
O resultado final será arredondado para:
(5)
Com isso, observa-se que os três dígitos mais baixos do segundo operando (654) são essencialmente perdidos ( Passo 6). Este é um erro de arredondamento.
Multiplicação e divisão
[editar | editar código-fonte]Multiplicação
[editar | editar código-fonte]Para realizar a multiplicação é necessário colocar os valores na notação de vírgula flutuante e verificar se a base (B) é igual, caso negativo deve-se realizar a mudança de base de um dos valores para que ambos tenham a mesma base, em seguida deve-se multiplicar suas mantissas (M) e somar seus expoentes (e).
Por exemplo, multiplicar X1=2.569854 x 103 por X2=5.238756 x 105 , percebe-se que base (B) é igual para ambos os valores B=10.
Passo 1: Representar os valores na notação de vírgula flutuante: +- M X B+-e.
X1=0.2569854 x 104 , onde M1=0.2569854 ; e1=+4
X2=0.5238756 x 106 , onde M2=0.5238756 ; e2=+6
Passo 2: Multiplica-se as mantissas (M) e soma-se os expoentes (e)
M1 x M2 = 0.2569854 x 0.5238756 = 0.1346283806 , esse produto é dado como verdadeiro.
e1 + e2 = 4 + 6 = 10
Passo 3: Realizar o arredondamento e em seguida apresenta o resultado.
0.1346283806 x 1010
Utilizando-se 7 casas decimas após a vírgula, temos que 0.1346283806 após arredondamento fica como: 0.1346284.
Portanto, o resultado obtido é:
0.1346284 x 1010
Divisão
[editar | editar código-fonte]Na operação de divisão, é necessário colocar os valores na notação de vírgula flutuante e verificar se a base (B) é igual, em caso negativo deve-se realizar a mudança de base de um dos valores para que ambos tenham a mesma base, em seguida deve-se dividir suas mantissas (M) e subtrair seus expoentes (e).
Por exemplo, dividir X1=5.349012 x 105 por X2=9.675421 x 103 , percebe-se que base (B) é igual para ambos os valores B=10.
Passo 1: Representar os valores na notação de vírgula flutuante: +- M X B+-e.
X1=0.5349012 x 106 , onde M1=0.59349012 ; e1=6
X2=0.9675421 x 104 , onde M2=0.5238756 ; e2=4
Passo 2: Divide-se as mantissas (M) e subtrai os expoentes (e).
Nesse ponto, deve-se atentar aos expoentes, pois a subtração é realizada subtraindo o expoente do dividendo (e1) pelo expoente do divisor (e2)
M1 / M2 = 0.5349012 / 0.9675421 = 0.5528454007 , esse resultado é dado como verdadeiro.
e1 - e2 = 6 - 4 = 2
Passo 3: Realizar o arredondamento e em seguida apresenta o resultado.
0.5528454007 x 102
Utilizando-se 7 casas decimas após a vírgula, temos que 0.5528454007 após arredondamento fica como: 0.5528454
Portanto, o resultado obtido é:
0.5528454 x 102
Implementação
[editar | editar código-fonte]Muitas frações decimais não podem ser representadas exatamente como frações binárias finitas. Por consequência, diversos números armazenados na máquina em váriaveis do tipo ponto flutuante (float, double, real) são apenas aproximações.[12]
Considere, por exemplo, a fração 1/3. Uma aproximação decimal seria:
- 0,3
- ou, melhor:
- 0,33
- ou, ainda melhor:
- 0,333
e assim por diante. Não existe uma fração finita capaz de resultar em exatamente 1/3.
Um outro exemplo interessante é a fração 1/10. Em muitas linguagens de programação, apesar de rotinas de impressão mostrar o valor 0,100000, se exibirmos o número com maior precisão (por exemplo, 20 casas decimais), veremos que o valor real armazenado será algo aproximado de:
0,10000000149001612000 (o valor pode mudar segundo o hardware e a linguagem utilizada).
Assim, ao programar é preciso ter cuidado com números em ponto flutuante, em especial com acumuladores e comparações.
Precisão da máquina e análise de erro reverso
[editar | editar código-fonte]A precisão da máquina é uma quantidade que caracteriza a exatidão de um sistema de ponto flutuante e é usada na análise de erros retroativos de algoritmos de ponto flutuante. É também conhecido como arredondamento da unidade ou épsilon da máquina. Normalmente denotado por Εmach, seu valor depende do arredondamento particular que está sendo usado.
, onde B é caracterizado como a base do sistema de ponto flutuante e P a precisão.
Com arredondamento para zero:
, onde este é o maior valor possível para o erro relativo.
Isso é importante, pois limita o erro relativo na representação de qualquer número real diferente de zero dentro do intervalo normalizado de um sistema de ponto flutuante:
A análise de erros reversos, cuja teoria foi desenvolvida e popularizada por James H. Wilkinson, pode ser usada para estabelecer que um algoritmo que implementa uma função numérica é numericamente estável. A abordagem básica é mostrar que embora o resultado calculado, devido a erros de arredondamento, não seja exatamente correto, é a solução exata para um problema próximo com dados de entrada levemente perturbados. Se a perturbação necessária for pequena, na ordem da incerteza nos dados de entrada, então os resultados são, em certo sentido, tão precisos quanto os dados "merecem". O algoritmo é então definido como estável com versões anteriores. A estabilidade é uma medida da sensibilidade a erros de arredondamento de um determinado procedimento numérico; em contraste, o número de condições de uma função para um determinado problema indica a sensibilidade inerente da função a pequenas perturbações em sua entrada e é independente da implementação usada para resolver o problema.
Como um exemplo trivial, considere uma expressão simples fornecendo o produto interno de (comprimento de dois) vetores x e y, então:
, onde fl indica a aritmética de ponto flutuante corretamente arredondado;
, onde .
E então:
;
Onde:
Para , por definição, que é a soma de dois dados de entrada levemente perturbados (na ordem de Εmach) e, portanto, é estável com versões anteriores.
Referências
- ↑ Randell, Brian (outubro de 1982). «From Analytical Engine to Electronic Digital Computer: The Contributions of Ludgate, Torres, and Bush». IEEE Annals of the History of Computing (4): 327–341. ISSN 1058-6180. doi:10.1109/MAHC.1982.10042. Consultado em 26 de março de 2021
- ↑ Rojas, R. April-June/1997. «Konrad Zuse's legacy: the architecture of the Z1 and Z3». IEEE Annals of the History of Computing (2): 5–16. doi:10.1109/85.586067. Consultado em 26 de março de 2021
- ↑ Rojas, Raul (7 de junho de 2014). «The Z1: Architecture and Algorithms of Konrad Zuse's First Computer». arXiv:1406.1886 [cs]. Consultado em 26 de março de 2021
- ↑ a b Kahan, Willian Morton (15 de julho de 1997). «The Baleful Effect of Computer Languages and Benchmarks upon Applied Mathematics, Physics and Chemistry» (PDF). John von Neumann Lecture. Consultado em 26 de março de 2021
- ↑ Randell, Brian , ed. (1982) [1973]. The Origins of Digital Computers: Selected Papers (3 ed.). Berlim; Nova York: Springer-Verlag . p. 244. ISBN 978-3-540-11319-5.
- ↑ people.eecs.berkeley.edu https://people.eecs.berkeley.edu/~wkahan/ieee754status/754story.html. Consultado em 26 de março de 2021 Em falta ou vazio
|título=
(ajuda) - ↑ Prof. MSc. Steinmacher,Igor, 2009, Imagem esquemática do Slide sobre Representação de Dados-Pontos Flutuantes
- ↑ Prof. MSc. Steinmacher, Igor, 2009, Exemplo retirado do Slide sobre Representação de Dados-Pontos Flutuantes
- ↑ http://pubs.opengroup.org/onlinepubs/009695399/frontmatter/refdocs.html
- ↑ http://www.ajdesigner.com/fl_ieee_754_word/ieee_32_bit_word.php
- ↑ «IEEE Standard for Floating-Point Arithmetic». doi:10.1109/ieeestd.2019.8766229. Consultado em 27 de junho de 2022
- ↑ a b «Floating Point Arithmetic: Issues and Limitations» (em inglês). Python v2.6.4 documentation
- ↑ Wiffin, Erik (19 de outubro de 2020). «0.30000000000000004». Consultado em 20 de novembro de 2020
- ↑ Zitoun, Heytem; Michel, Claude; Rueher, Michel; Michel, Laurent (7 de julho de 2018). «Sub-domain Selection Strategies For Floating Point Constraint Systems». Springer. International Conference on Principles and Practice of Constraint Programming. Consultado em 20 de novembro de 2011 line feed character character in
|titulo=
at position 51 (ajuda) - ↑ «LABVIEW NXG 5.0 MANUAL». NATIONAL INSTRUMENTS CORP. 9 de agosto de 2019. Consultado em 20 de novembro de 2020
- ↑ de Sena, Dr. G.J (2017). «Aritmética de ponto flutuante e erros» (PDF). Unesp. Consultado em 18 de abril de 2021
- ↑ Santos, Victor a. M.; Sena, Guilherme Gaudereto; Silva, Leandro Rodrigues Manso; Filho, Luciano Manhães De Andrade (2019). «IMPLEMENTAÇÃO DE CIRCUITOS ARITMÉTICOS EM PONTO FLUTUANTE, UTILIZANDO FORMATO COM NÚMERO DE BITS CONFIGURÁVEL». Congresso Brasileiro de Automática - CBA (em inglês) (1). ISSN 0103-1759. Consultado em 3 de maio de 2021
- ↑ «Padrão IEEE 754 para Aritmética Binária de Ponto Flutuante | Engenharia da computação | Números». Scribd. Consultado em 3 de maio de 2021