O formato de ponto flutuante de precisão simples (por vezes chamado de FP32, float32 ou float) é um formato de número de computador que ocupa habitualmente 32 bits na memória de computador; representa uma ampla gama de valores numéricos utilizando um ponto flutuante.

Uma variável de ponto flutuante pode representar uma gama de números mais vasta do que uma variável de ponto fixo da mesma largura de bits, ao custo da precisão. Uma variável de inteiro de 32 bits com sinal tem um valor máximo de 231 − 1 = 2.147.483.647, enquanto uma variável de ponto flutuante de 32 bits em base 2 segundo a IEEE 754 tem um valor finito máximo de (2 − 2−23) × 2127 ≈ 3,4028235 × 1038. Todos os números inteiros com sete ou menos dígitos decimais, e qualquer 2n para um número inteiro −149 ≤ n ≤ 127, podem ser convertidos exatamente para um valor de ponto flutuante de precisão simples IEEE 754.

No padrão IEEE 754, o formato de 32 bits em base 2 é referido oficialmente como binary32; era chamado de single (precisão simples) no IEEE 754-1985. O IEEE 754 especifica tipos adicionais de ponto flutuante, tais como o formato de precisão dupla de 64 bits em base 2 e, mais recentemente, representações em base 10.

Uma das primeiras linguagens de programação a fornecer tipos de dados de ponto flutuante de precisão simples e dupla foi o Fortran. Antes da adoção generalizada do IEEE 754-1985, a representação e as propriedades dos tipos de dados de ponto flutuante dependiam do fabricante de computadores e do modelo do computador, bem como das decisões tomadas pelos projetistas da linguagem de programação. Por exemplo, o tipo de dados de precisão simples do GW-BASIC era o formato de ponto flutuante MBF de 32 bits.

A precisão simples é denominada SINGLE-FLOAT no Common Lisp; float binary(p) com p≤21, float decimal(p) com o valor máximo de p dependendo de se o atributo DFP (IEEE 754 DFP) se aplica, no PL/I; float em C com suporte IEEE 754, C++ (se estiver em C), C# e Java; Float em Haskell e Swift; e Single em Object Pascal (Delphi), Visual Basic e MATLAB. Contudo, float em Python, Ruby, PHP e OCaml, e single em versões do Octave anteriores à 3.2, referem-se a números de precisão dupla. Na maioria das implementações de PostScript e em alguns sistemas embarcados, a única precisão suportada é a simples.

Padrão IEEE 754: binary32

O padrão IEEE 754 especifica um binary32 como tendo: Bit de sinal: 1 bit Largura do expoente: 8 bits Precisão do significando: 24 bits (23 armazenados explicitamente)

Isto proporciona de 6 a 9 algarismos significativos de precisão decimal. Se uma string decimal com no máximo 6 algarismos significativos for convertida para o formato de precisão simples IEEE 754, resultando em um número normal, e depois convertida de volta para uma string decimal com o mesmo número de algarismos, o resultado final deve coincidir com a string original. Se um número de precisão simples IEEE 754 for convertido para uma string decimal com pelo menos 9 algarismos significativos e, em seguida, convertido de volta para a representação de precisão simples, o resultado final deve coincidir com o número original.

O bit de sinal determina o sinal do número, que é também o sinal do significando. "1" significa negativo. O campo do expoente é um número inteiro de 8 bits sem sinal, em forma polarizada (*biased form*): um valor de 127 representa o expoente zero real. Os expoentes variam de −126 a +127 (assim, 1 a 254 no campo do expoente), porque os valores do expoente polarizado 0 (todos os bits em 0) e 255 (todos os bits em 1) são reservados para números especiais (números subnormais, zeros com sinal, infinitos e NaN).

O significando verdadeiro dos números normais inclui 23 bits de fração à direita do ponto binário e um bit líder implícito (à esquerda do ponto binário) com valor 1. Números subnormais e zeros (que são os números de ponto flutuante menores em magnitude do que o menor número normal positivo) são representados com o valor do expoente polarizado 0, dando ao bit líder implícito o valor 0. Assim, apenas 23 bits de fração do significando aparecem no formato de memória, mas a precisão total é de 24 bits (equivalente a log10(224) ≈ 7,225 dígitos decimais) para valores normais; os subnormais têm uma precisão que degrada gradualmente até 1 bit para o menor valor diferente de zero.

Os bits estão dispostos da seguinte forma:

Imagem:Float example.svg

O valor real assumido por um dado dado binary32 de 32 bits com um sinal dado, expoente polarizado E (o inteiro de 8 bits sem sinal) e uma fração de 23 bits é: , o que resulta em:

Neste exemplo: , , , , . portanto: .

Nota: , , , .

Codificação do expoente O expoente do ponto flutuante binário de precisão simples é codificado usando uma representação binária com deslocamento (ou excesso), com o deslocamento zero sendo 127; também conhecido como viés de expoente no padrão IEEE 754. Emin = 01H−7FH = −126 Emax = FEH−7FH = 127 Viés de expoente = 7FH = 127

Assim, para obter o expoente real conforme definido pela representação binária com deslocamento, o deslocamento de 127 deve ser subtraído do expoente armazenado.

Os expoentes armazenados 00H e FFH são interpretados de forma especial.

Expoente fração = 0 fração ≠ 0 Equação 00H = 000000002 ±zeronúmero subnormal 01H, ..., FEH = 000000012, ..., 111111102 valor normal FFH = 111111112 ±infinito NaN (silencioso, sinalizador)

O valor normal positivo mínimo é e o valor positivo mínimo (subnormal) é .

Convertendo decimal para binary32 Em geral, consulte o próprio padrão IEEE 754 para a conversão estrita (incluindo o comportamento de arredondamento) de um número real para o seu formato binary32 equivalente.

Aqui podemos mostrar como converter um número real na base 10 para o formato IEEE 754 binary32 usando o seguinte esboço: Considere um número real com uma parte inteira e uma parte fracionária, como 12.375. Converta e normalize a parte inteira para o binário. Converta a parte fracionária usando a técnica a seguir. Adicione os dois resultados e ajuste-os para produzir uma conversão final adequada.

Conversão da parte fracionária: Considere 0.375, a parte fracionária de 12.375. Para convertê-la em uma fração binária, multiplique a fração por 2, tome a parte inteira e repita com a nova fração por 2 até que uma fração zero seja encontrada ou até que o limite de precisão seja atingido, que é de 23 dígitos de fração para o formato IEEE 754 binary32.

, a parte inteira representa o dígito da fração binária. Multiplique novamente 0.750 por 2 para prosseguir.

, fração = 0.011, termina.

Vemos que pode ser representado exatamente em binário como . Nem todas as frações decimais podem ser representadas em uma fração binária de dígitos finitos. Por exemplo, 0.1 decimal não pode ser representado exatamente em binário, apenas aproximado. Portanto:

Como o formato IEEE 754 binary32 exige que os valores reais sejam representados no formato (veja Número normalizado, Número desnormalizado), 1100.011 é deslocado para a direita em 3 dígitos para se tornar .

Finalmente, podemos ver que: .

Do qual deduzimos: O expoente é 3 (e, na forma polarizada, é portanto ) A fração é 100011 (olhando para a direita do ponto binário)

A partir desses dados, podemos formar a representação resultante de 32 bits no formato IEEE 754 binary32 de 12.375:

Nota: considere converter 68.123 para o formato IEEE 754 binary32: Usando o procedimento acima, espera-se obter com os últimos 4 bits sendo 1001. No entanto, devido ao comportamento de arredondamento padrão do formato IEEE 754, o que se obtém é , cujos últimos 4 bits são 1010.

Exemplo 1: Considere o decimal 1. Podemos ver que:

Do qual deduzimos: O expoente é 0 (e, na forma polarizada, é portanto ) A fração é 0 (olhando para a direita do ponto binário em 1.0, tudo é )

A partir desses dados, podemos formar a representação resultante de 32 bits no formato IEEE 754 binary32 do número real 1:

Exemplo 2: Considere o valor 0.25. Podemos ver que:

Do qual deduzimos: O expoente é −2 (e, na forma polarizada, é ) A fração é 0 (olhando para a direita do ponto binário em 1.0, tudo é zero)

A partir desses dados, podemos formar a representação resultante de 32 bits no formato IEEE 754 binary32 do número real 0.25:

Exemplo 3: Considere o valor 0.375. Vimos que

Portanto, após determinar uma representação de 0.375 como , podemos proceder como acima: O expoente é −2 (e, na forma polarizada, é ) A fração é 1 (olhando para a direita do ponto binário em 1.1, temos um único )

A partir desses dados, podemos formar a representação resultante de 32 bits no formato IEEE 754 binary32 do número real 0.375:

Convertendo binary32 para decimal Se o valor binary32, neste exemplo, estiver em hexadecimal, primeiro convertemos para binário:

em seguida, dividimo-lo em três partes: bit de sinal, expoente e significando. Bit de sinal: Expoente: Significando:

Adicionamos então o 24º bit implícito ao significando: Significando:

e decodificamos o valor do expoente subtraindo 127: Expoente bruto: Expoente decodificado:

Cada um dos 24 bits do significando (incluindo o 24º bit implícito), do bit 23 ao bit 0, representa um valor, começando em 1 e dividindo-se por dois a cada bit, da seguinte forma:

bit 23 = 1 bit 22 = 0.5 bit 21 = 0.25 bit 20 = 0.125 bit 19 = 0.0625 bit 18 = 0.03125 bit 17 = 0.015625 . . bit 6 = 0.00000762939453125 bit 5 = 0.000003814697265625 bit 4 = 0.0000019073486328125 bit 3 = 0.00000095367431640625 bit 2 = 0.000000476837158203125 bit 1 = 0.0000002384185791015625 bit 0 = 0.00000011920928955078125

O significando neste exemplo tem três bits definidos: bit 23, bit 22 e bit 19. Agora podemos decodificar o significando adicionando os valores representados por esses bits. Significando decodificado:

Então, precisamos multiplicar pela base, 2, elevada à potência do expoente, para obter o resultado final:

Portanto:

Isso é equivalente a:

onde é o bit de sinal, é o expoente e é o significando.

Limitações de precisão em valores decimais (entre 1 e 16777216) Decimais entre 1 e 2: intervalo fixo 2−23 (1+2−23 é o próximo float maior após 1) Decimais entre 2 e 4: intervalo fixo 2−22 Decimais entre 4 e 8: intervalo fixo 2−21 ... Decimais entre 2n e 2n+1: intervalo fixo 2n−23 ... Decimais entre 222=4.194.304 e 223=8.388.608: intervalo fixo 2−1=0.5 Decimais entre 223=8.388.608 e 224=16.777.216: intervalo fixo 20=1

Limitações de precisão em valores inteiros Inteiros entre -16.777.216 e 16.777.216 (incluindo 0) podem ser representados exatamente. Inteiros entre 224=16.777.216 e 225=33.554.432 arredondam para um múltiplo de 2 (número par). Inteiros entre 225 e 226 arredondam para um múltiplo de 4. ... Inteiros entre 2n e 2n+1 arredondam para um múltiplo de 2n−23. ... Inteiros entre 2127 e 2128 arredondam para um múltiplo de 2104. Inteiros maiores ou iguais a 2128 são arredondados para "infinito".

Casos notáveis de precisão simples Estes exemplos são dados na representação de bits, em hexadecimal e binário, do valor de ponto flutuante. Isso inclui o sinal, o expoente (polarizado) e o significando.

0 00000000 000000000000000000000012 = 0000 000116 = 2−126 × 2−23 = 2−149 ≈ 1,4012984643 × 10−45 (menor número subnormal positivo)

0 00000000 111111111111111111111112 = 007f ffff16 = 2−126 × (1 − 2−23) ≈ 1,1754942107 × 10−38 (maior número subnormal)

0 00000001 000000000000000000000002 = 0080 000016 = 2−126 ≈ 1,1754943508 × 10−38 (menor número normal positivo)

0 11111110 111111111111111111111112 = 7f7f ffff16 = 2127 × (2 − 2−23) ≈ 3,4028234664 × 1038 (maior número normal)

0 01111110 111111111111111111111112 = 3f7f ffff16 = 1 − 2−24 ≈ 0,999999940395355225 (maior número menor que um)

0 01111111 000000000000000000000002 = 3f80 000016 = 1 (um)

0 01111111 000000000000000000000012 = 3f80 000116 = 1 + 2−23 ≈ 1,00000011920928955 (menor número maior que um)

1 10000000 000000000000000000000002 = c000 000016 = −2