Ponto flutuante

Digite um número decimal. Os passos abaixo detalham a conversão, feita exatamente como a faria no papel, e a linha no topo mostra o que um computador acaba por guardar.

A carregar a simulação interativa...
Lição

A teoria — Ponto flutuante284 palavras

Um número de ponto flutuante é um número inteiro multiplicado por uma potência de dois: (−1)s × 1.f × 2E−1023. O formato decide quantos bits pertencem a E e quantos a f, e essa única divisão define tanto o alcance do formato quanto a sua precisão ao distinguir dois números.

O que significa cada símbolo

s
o bit de sinal, 0 para positivo e 1 para negativo. Permanece isolado em vez de ser incorporado no número, razão pela qual o formato apresenta tanto um +0 como um −0.
E
o campo do expoente, armazenado com o acréscimo de 1023 para que possa assumir valores negativos sem precisar de um sinal próprio. É ele que escolhe em que intervalo o número se encontra, e é o intervalo que decide a distância entre os vizinhos.
f
a fração: 52 bits que sucedem a um 1 inicial que nunca é armazenado, dado que um número normalizado começa sempre por um. Estes 52 bits representam toda a precisão do formato, à qual o expoente não acrescenta nada.
Pressupõe
Que o número é finito e normal. Abaixo de 2−1022, o 1 inicial é omitido e o formato mantém-se sacrificando a precisão. Como resultado, o menor double positivo é 4,94 × 10−324 e carrega um único bit de significando.
Falha quando
Em dois lugares, ambos em código real. Comparar dois valores calculados com = falha sempre que venham de vias distintas, porque rotas diferentes introduzem arredondamentos diferentes. Uma soma longa depende também da ordem de adição: some uma lista numa direção e depois na outra, e os totais divergem. Somar primeiro os termos menores é a forma de perder menos.

Oito entre mil 🖖

Dos números de 0,001 a 1,000, exatamente oito são mantidos sem nenhum erro: 0,125; 0,25; 0,375; 0,5; 0,625; 0,75; 0,875 e 1. Uma fração binária é uma soma de metades, quartos, oitavos e por aí adiante, e um denominador de 1000 contém um fator de 125 que nenhuma potência de dois jamais eliminará. Digite 0,375 e a ferramenta considera o valor exato. Digite 0,376 e ela não o fará.

0,1 + 0,2 cai exatamente a meio 🖖

Os dois valores armazenados somam 0,3000000000000000166533453693773481063544750213623046875, e esse é o ponto médio preciso entre os dois números de dupla precisão de cada lado de 0,3. A adição propriamente dita é impecável. O empate tem de ser desfeito de alguma forma, e a regra consiste em adotar o vizinho cujo último bit seja par. O valor de dupla precisão abaixo de 0,3 termina a sua fração num bit ímpar e o que se encontra acima termina num bit par, pelo que a soma é arredondada para cima. É daí que provém a cauda do número 0,30000000000000004.

Menos bits, a resposta certa 🖖

Selecione binary32 com os mesmos dois números. O 0,1 + 0,2 dá 0,300000011920928955078125, que é exatamente a forma como o 0,3 é armazenado nesse formato. O célebre fracasso desta conta exige que a soma resulte num empate. Com 24 bits, o resultado fica a um quarto de intervalo de distância de o ser, pelo que arredonda de volta para o número que esperava. Tem metade da precisão e a resposta que pretendia.

O intervalo duplica a cada potência de dois 🖖

Em qualquer ponto entre 0,0625 e 0,125, a distância de um número representável para o seguinte é de 1,39 × 10⁻¹⁷, sem sofrer qualquer variação dentro dessa faixa. Ao passar para a faixa superior, a distância duplica. A escadaria no gráfico ilustra precisamente isso: um degrau por cada potência de dois. É por este motivo que o mesmo formato consegue armazenar 10⁻³⁰⁰ e 10³⁰⁰, mas é incapaz de guardar o 9007199254740993.

Problema resolvido na íntegra

  1. Um sistema de pagamentos armazena montantes em libras no formato binary64. Mostre que £0,10 e £0,20 são ambos armazenados ligeiramente por excesso, que a sua soma não dá £0,30, e explique o que um engenheiro de pagamentos faz para solucionar o problema.

    1. O valor 0,1 na base dois é 0,0001 seguido de 1001 a repetir-se infinitamente. Um décimo requer um cinco no seu denominador e uma fração binária é composta apenas por fatores de dois, de modo que a expansão nunca termina.

    2. São mantidos 53 algarismos binários e os restantes são eliminados por arredondamento. Neste caso arredondam para cima, pelo que o valor armazenado fica 5,55 × 10⁻¹⁸ acima de 0,1. O passo de arredondamento na página ilustra essa direção com uma seta.

    3. O número 0,2 corresponde a esses mesmos 53 algarismos mas com o expoente superior em uma unidade, logo o seu erro é o dobro exato: 1,11 × 10⁻¹⁷. Introduza 0,2 na caixa e compare os dois cartões de erro.

    4. Quando somados, os dois valores armazenados recaem exatamente no ponto médio entre os dois números de dupla precisão de cada lado de 0,3. Em caso de empate, escolhe-se o vizinho que termina num bit par, que aqui corresponde ao valor imediatamente superior.

    5. Assim, o resultado devolvido é 0,3000000000000000444089209850062616169452667236328125, e todos os cálculos seguintes vão arrastá-lo.

    6. Agora digite 10 e 20 em vez de 0,1 e 0,2. Ambos são números inteiros bastante inferiores a 2⁵³, ambos são armazenados de forma exata, e 10 + 20 é 30 sem qualquer perda no processo.

    Resposta

    Guarde o dinheiro como um número inteiro da unidade mais pequena, pence em vez de libras, e a aritmética torna-se exata porque todos os inteiros até 2⁵³ são exatos. O único arredondamento que resta é aquele que você próprio escreve, no momento em que decidir fazê-lo, e para o qual pode apontar. A ferramenta mostra os dois lados em dez segundos: digite 0,1 e o cartão de erro não será nulo; digite 10 e será.

Problemas de exemplo

  • 0,1 - O valor 0,1 é guardado como 0,1000000000000000055511151231257827021181583404541015625, e o 0,2 sofre de um excesso duas vezes superior. A soma de ambos cai exatamente a meio caminho entre os dois números em redor do 0,3. É então aplicada a regra de desempate, que decide arredondar para cima.
  • 0,375 - A linha de base dois para após três algarismos em vez de continuar infinitamente, e a ferramenta considera o valor exato. 0,375 é igual a 3/8, e uma fração binária é constituída por oitavos. Mude o último algarismo para 0,376 e a expansão nunca terminará.
  • 0,1 em 32 bits - O mesmo 0,1 em 24 bits de significando em vez de 53: mantido como 0,100000001490116119384765625, e a ferramenta indica 7,22 dígitos decimais. Adicione 0,2 aqui e a resposta é 0,300000011920928955078125, que corresponde exatamente à forma como o 0,3 é armazenado neste formato.
  • 2⁵³ + 1 - Acima de 2⁵³, o intervalo atinge o valor 2, perdendo-se assim um em cada dois números inteiros. O 9007199254740993 encontra-se exatamente entre dois deles, e o desempate atira-o para baixo, para 9007199254740992, com um erro de −1. Somar 1 a este valor não muda nada, pela mesma razão.
  • 10¹⁶ + 1 - Tanto o 10¹⁶ como o 1 são representados com exatidão. Contudo, 10¹⁶ + 1 resulta em 10¹⁶. O intervalo aqui é 2, logo 10000000000000001 constitui um empate entre dois vizinhos. A regra do último bit par, que atirou o 0,1 + 0,2 para cima, empurra este de volta para baixo.