Vírgula flutuante e IEEE 754

Vírgula fixa em formato Q, normais e subnormais, arredondamento e operações IEEE 754.

TLDR

Perguntar sobre esta página

ChatGPTClaudePerplexityGrokGeminiCopiar e abrirDeepSeekCopiar e abrir

Guardar o inteiro 26 e interpretá-lo em unidades de 1/81/8 dá 26/8=3,2526/8=3{,}25. Nenhum bit da palavra assinala a vírgula, pois essa escala faz parte do acordo entre o circuito e o programa; na vírgula fixa, o passo é constante, enquanto na vírgula flutuante um expoente guardado com o significando altera a escala e o espaçamento entre valores.

Convenção Qm.n

Usamos Qm.nQm.n com mm bits para a parte inteira incluindo o sinal e nn bits fracionários; a largura total é N=m+nN=m+n. O inteiro XX está em complemento para dois e representa

x=X 2−n.x=X\,2^{-n}.

O intervalo é [−2m−1, 2m−1−2−n][-2^{m-1},\,2^{m-1}-2^{-n}] e a resolução é 2−n2^{-n}. Em Q4.4Q4.4, os 8 bits representam de −8-8 a 7,93757{,}9375, em passos de 0,06250{,}0625.

Para codificar −2,75-2{,}75 em Q4.4Q4.4, calcula X=−2,75×16=−44X=-2{,}75\times16=-44. Em 8 bits, 256−44=212=D416256-44=212=\mathrm{D4}_{16}. Para descodificar D4, lê primeiro −44-44 em complemento para dois e só depois divide por 16.

Escolher um formato

Queremos medir valores entre −20-20 e +20+20 com passo não superior a 0,010{,}01. Precisamos de 2−n≤0,012^{-n}\le0{,}01: n=7n=7 dá 1/128≈0,00781251/128\approx0{,}0078125. Para o intervalo, m=5m=5 só chega a menos de 16, enquanto m=6m=6 chega a menos de 32, portanto Q6.7Q6.7, com 13 bits, satisfaz ambas as condições.

Se a palavra disponível só tiver 12 bits, não podemos manter essas duas escolhas. Temos de reduzir o intervalo, aceitar um passo maior ou aumentar a largura, porque a precisão e o intervalo competem pelos bits.

Um valor não múltiplo da resolução exige arredondamento ou truncatura. Em Q4.4Q4.4, 0,1×16=1,60{,}1\times16=1{,}6: arredondar para o inteiro mais próximo dá X=2X=2 e valor 0,1250{,}125, enquanto truncar para zero dá X=1X=1 e valor 0,06250{,}0625. Indica a política usada.

Adição e mudança de escala

Com a mesma escala, somamos os inteiros: x+y=(X+Y)2−nx+y=(X+Y)2^{-n}. Em Q4.4Q4.4, 1,51{,}5 é 24 e −0,75-0{,}75 é −12-12, por isso a soma 12 representa 0,750{,}75; o teste de overflow é o da palavra inteira com sinal.

Se as escalas diferirem, alinha-as primeiro. Converter de Q4.4Q4.4 para Q4.6Q4.6 exige multiplicar o código por 222^2, acrescentando dois bits fracionários. Converter no sentido inverso perde bits e pode exigir arredondamento. Um deslocamento à direita aritmético de negativos arredonda para baixo; não equivale sempre a truncar para zero.

Por exemplo, soma 1,5 guardado com quatro bits fracionários a 0,25 guardado com seis. Os códigos são 24 e 16; na escala de seis bits, o primeiro passa a 24×4=9624\times4=96. Agora 96+16=11296+16=112 representa 112/64=1,75112/64=1{,}75, enquanto somar diretamente 24+16 misturaria unidades diferentes.

Multiplicação e divisão

Se x=X2−nx=X2^{-n} e y=Y2−ny=Y2^{-n}, o produto inteiro XYXY tem escala 2−2n2^{-2n}. Para voltar à escala inicial, calcula XY/2nXY/2^n com largura suficiente para o produto intermédio.

Em Q4.4Q4.4, 1,5×(−0,75)1{,}5\times(-0{,}75) usa 24×(−12)=−28824\times(-12)=-288. Dividindo por 16 obtemos −18-18, que representa −1,125-1{,}125. O produto −288-288 não cabe em 8 bits, embora o resultado final caiba. Fazer a multiplicação já em 8 bits destruiria o resultado.

Para obter x/yx/y na escala 2−n2^{-n}, com y≠0y\ne0, calcula com numerador alargado e arredondamento definido

Z=X 2nY,y≠0,Z=\frac{X\,2^n}{Y},\quad y\ne0,

como em 1,5/0,751{,}5/0{,}75, que dá (24×16)/12=32(24\times16)/12=32, ou seja, 2.

Com escalas n1,n2n_1,n_2 nas entradas e n3n_3 no resultado, o produto requer um deslocamento de n1+n2−n3n_1+n_2-n_3 posições à direita, se esse valor for não negativo. Separar a escala da largura evita confundir overflow com perda de precisão.

Campos e valores

O sinal ss vale 0 para positivo e 1 para negativo. A tabela indica o número de bits de cada campo e o bias do formato.

FormatoSinal ssExpoente EEFração FFBias
binary321823127
binary64111521023
bfloat16187127

Aqui EE e FF são os inteiros sem sinal lidos dos respetivos campos. Emax⁡E_{\max} é o expoente com todos os bits a 1: 255 em binary32. O bias é a constante subtraída a EE para obter o expoente real. pp é o número de bits da fração.

Se 0<E<Emax⁡0<E<E_{\max}, o número é normal, com

x=(−1)s(1+F2p)2E−bias,x=(-1)^s\left(1+\frac{F}{2^p}\right)2^{E-\mathrm{bias}},

onde o 1 antes da vírgula é implícito; assim binary32 tem 24 bits de precisão no significando dos normais.

Se E=0E=0, não há esse 1, com

x=(−1)sF2p21−bias.x=(-1)^s\frac{F}{2^p}2^{1-\mathrm{bias}}.

Com F≠0F\ne0 obtemos um subnormal. Com F=0F=0 obtemos +0+0 ou −0-0.

Se todos os bits do expoente forem 1, o valor depende só da fração: F=0F=0 significa infinito e F≠0F\ne0 significa NaN, not a number. NaN não é um número muito grande; é o código para resultados sem valor numérico.

Binary32 e binary64 são formatos IEEE 754. Bfloat16 usa a disposição indicada na tabela; não se deve inferir que qualquer operação ou conversão de bfloat16 tenha as mesmas regras de um ambiente IEEE 754 completo. Nos exemplos de arredondamento abaixo usamos explicitamente o modo mais próximo, com empates para par.

Codificar um valor

Codifica −13,25-13{,}25 em binary32. O módulo é 1101,012=1,101012×231101{,}01_2=1{,}10101_2\times2^3, portanto s=1s=1, E=3+127=130=100000102E=3+127=130=10000010_2 e a fração é 10101 seguida de 18 zeros:

1 | 10000010 | 10101000000000000000000

Agrupar em grupos de quatro bits dá 0xC1540000. Para descodificar, reconstrói −(1+1/2+1/8+1/32)×8=−13,25-(1+1/2+1/8+1/32)\times8=-13{,}25. Não interpretes a palavra completa em complemento para dois.

Limites e espaçamento

Em binary32, o menor normal positivo é 2−1262^{-126} e o menor subnormal positivo é 2−1492^{-149}. O maior finito é (2−2−23)2127(2-2^{-23})2^{127}. Os subnormais mantêm passos de 2−1492^{-149} perto de zero, com menos bits significativos à medida que o valor diminui.

No intervalo [2e,2e+1)[2^e,2^{e+1}), os normais binary32 têm espaçamento 2e−232^{e-23}. Entre 1 e 2 é 2−232^{-23}; entre 2 e 4 é 2−222^{-22}. Em bfloat16, o menor representável maior que 2 é 2+2−62+2^{-6}, porque o expoente tem a mesma largura de binary32 mas a precisão é muito menor.

Somar e subtrair

Para somar 5,5+1,255{,}5+1{,}25, escreve 1,0112×221{,}011_2\times2^2 e 1,012×201{,}01_2\times2^0. Os bits só podem ser somados por coluna quando têm os mesmos pesos, por isso conserva o expoente 2 e desloca o segundo significando duas posições à direita:

   1,0110 × 2²       5,5
 + 0,0101 × 2²       1,25
   ──────────
   1,1011 × 2²       6,75

O zero acrescentado ao primeiro significando só completa a coluna. O resultado já está normalizado, pois o significando está entre 1 e 2.

Subtrair usa o mesmo alinhamento: 5,5−5,255{,}5-5{,}25 dá (1,011−1,0101)×22=0,0001×22=1×2−2=0,25(1{,}011-1{,}0101)\times2^2=0{,}0001\times2^2=1\times2^{-2}=0{,}25. Depois de uma quase anulação, pode ser preciso normalizar deslocando para a esquerda.

No formato finito, conserva bits adicionais durante a conta e arredonda no fim. O modo usual é o mais próximo, com empates para o significando cujo último bit conservado é par. Truncar sempre não implementa esta regra.

Um modelo pequeno com três bits de fração ajuda a ver um empate. Entre 1 e 2, os números avançam de 1/8 em 1/8; o valor 1+1/16=1,000121+1/16=1{,}0001_2 fica a meio de 1,000 e 1,001, por isso escolhemos 1,000, cujo último bit é 0. Já 1+3/16=1,001121+3/16=1{,}0011_2 fica a meio de 1,001 e 1,010, por isso escolhemos 1,010. Empate para par pode arredondar para cima ou para baixo; este modelo serve apenas para explicar a regra, pois binary32 conserva 23 bits de fração.

Multiplicar e perder precisão

Na multiplicação, trata cada campo em separado: XOR dos sinais, soma dos expoentes reais e produto dos significandos. Para 1,5×2,51{,}5\times2{,}5, os significandos dão (1,1×1,01)=1,111(1{,}1\times1{,}01)=1{,}111, com expoente 1, ou seja, 3,753{,}75. Se o produto dos significandos atingir 2, divide-o por 2 e aumenta o expoente em 1.

Overflow pode produzir infinito; resultados demasiado pequenos podem tornar-se subnormais ou zero. Reduzir a precisão também exige arredondar, mesmo dentro do intervalo: 1,11{,}1 não tem representação binária finita, por isso binary64 guarda-o arredondado a 52 bits e a passagem a binary32 arredonda de novo a 23 bits. No exercício de bfloat16 do volume 1, a ausência de subnormais é uma hipótese local desse enunciado, não uma propriedade geral do formato.

A adição não é associativa em geral. Em binary32, 224+12^{24}+1 arredonda para 2242^{24}, pois o passo é 2 e o empate conserva o último bit par. Assim (224+1)−224=0(2^{24}+1)-2^{24}=0, mas 224+(1−224)=12^{24}+(1-2^{24})=1.

Sinal11 bit
Expoente100000108 bits
Fração1010100000000000000000023 bits
Classe
Normal
Expoente armazenado
130
Expoente real
3
Significando
1,65625
Valor
−13,25

A visualização separa sinal, expoente e fração e aplica as regras de binary32, sem efetuar uma nova operação aritmética entre floats. Os bits são exatos; a escrita decimal de valores muito pequenos ou grandes é uma aproximação. Para NaN e infinito, a fórmula dos números finitos não se aplica.

Exercícios

Escolher intervalo e passo

Escolhe o menor formato Qm.n com sinal que representa de -12 a +12 com passo não superior a 1/32. Indica a largura.

Pista

Escolhe n pelo passo e m pelo intervalo.

Mais uma pista

m inclui o bit de sinal; Q4 não chega a +12.

Solução

n=5n=5 dá passo 1/32. m=4m=4 dá máximo menor que 8, insuficiente; m=5m=5 dá máximo 16−1/3216-1/32. Logo Q5.5, largura 10 bits. Os extremos pedidos são múltiplos do passo e ficam no intervalo.

Confere a tua resposta:

  • Q5.5, largura 10 bits.
  • Confirma intervalo e passo 1/32.

Erros frequentes

Não escolhas m=4 contando apenas os bits da magnitude.

Voltar à explicação
Escala do produto

Em Q4.4, calcula 2,5×(−1,25)2{,}5\times(-1{,}25) através dos códigos inteiros. Explica a largura do intermédio.

Pista

Os códigos são os valores multiplicados por 16.

Mais uma pista

O produto tem inicialmente 8 bits fracionários.

Solução

X=40, Y=-20. O produto inteiro é -800, com escala 1/256. Para voltar a Q4.4, divide por 16: Z=-50, representando -3,125. -800 não cabe em 8 bits, pelo que o produto tem de ser calculado em largura maior. O resultado final -50 cabe.

Confere a tua resposta:

  • Códigos 40 e -20; produto intermédio -800.
  • Intermédio mais largo que oito bits; código final -50, valor -3,125.

Erros frequentes

Não dividas o produto pela escala antes de o calcular num registo com largura suficiente.

Voltar à explicação
Três regras para um negativo

Converte o código X=-7 de uma escala com n=3 para n=1. Compara truncatura para zero, arredondamento para baixo e arredondamento ao mais próximo.

Pista

O novo código exato seria -7/4.

Mais uma pista

O valor original é -0,875; a nova resolução é 0,5.

Solução

O código ideal é -1,75. Truncar para zero dá -1, valor -0,5. Arredondar para baixo dá -2, valor -1. O mais próximo também dá -2, porque -1 está a 0,125 do original e -0,5 a 0,375. Um shift aritmético por 2 implementa a opção para baixo neste caso.

Confere a tua resposta:

  • Códigos -1 para zero; -2 para baixo e mais próximo.
  • Relaciona os códigos com valores -0,5 e -1.

Erros frequentes

Para negativos, um shift aritmético não é truncatura para zero.

Voltar à explicação
Codificar binary32

Codifica 6,56{,}5 em binary32. Dá sinal, expoente armazenado, fração e hexadecimal.

Pista

6,5 é 110,1 em binário.

Mais uma pista

Normaliza para 1,101×2².

Solução

s=0s=0, expoente real 2, E=129=100000012E=129=10000001_2. A fração é 101 seguida de 20 zeros. A palavra é 0 | 10000001 | 10100000000000000000000, hexadecimal 0x40D00000. A reconstrução é (1+1/2+1/8)×4=6,5(1+1/2+1/8)\times4=6,5.

Confere a tua resposta:

  • Sinal 0, E=129, fração começa por 101.
  • Hexadecimal 40D00000 e reconstrução 6,5.

Erros frequentes

O expoente armazenado inclui bias; a fração não guarda o 1 implícito.

Voltar à explicação
Classificar os campos

Classifica 0x80000000, 0x00000001, 0x7F800000 e 0xFFC00000 em binary32.

Pista

Separa expoente e fração antes de usar o sinal.

Mais uma pista

Expoente todo 1 só é infinito quando a fração é zero.

Solução

80000000 é -0; 00000001 é o menor subnormal positivo, 2−1492^{-149}; 7F800000 é +infinito; FFC00000 é NaN, porque E=255 e F é diferente de 0. O sinal 1 não transforma NaN num número negativo ordenável.

Confere a tua resposta:

  • Identifica -0, menor subnormal, +infinito e NaN.
  • Usa a fração para distinguir NaN de infinito.

Erros frequentes

Nem todo o padrão com expoente máximo é infinito, porque a fração decide entre infinito e NaN.

Voltar à explicação
Precisão local de bfloat16

Qual é a distância entre números bfloat16 consecutivos entre 8 e 16? Qual é o menor representável maior que 8?

Pista

8 corresponde a expoente real 3.

Mais uma pista

Há 7 bits de fração, pelo que o passo é 2^(3−7).

Solução

O passo é 2−4=1/16=0,06252^{-4}=1/16=0,0625. O número seguinte é 8+0,0625=8,06258+0,0625=8,0625. O passo não é 2−72^{-7} em todo o intervalo, porque o expoente altera a escala.

Confere a tua resposta:

  • Passo 0,0625 e número seguinte 8,0625.
  • Usa expoente real 3 e sete bits de fração.

Erros frequentes

Usar o passo perto de 1 em qualquer magnitude ignora o papel do expoente, porque o passo cresce com o intervalo.

Voltar à explicação
Alinhar, somar e normalizar

Faz em binário 3,5+0,753{,}5+0{,}75 e 1,5×1,751{,}5\times1{,}75. Mostra a normalização.

Pista

Na soma alinha os expoentes; no produto multiplica significandos.

Mais uma pista

3,5 é 1,11×2¹; 0,75 é 1,1×2⁻¹.

Solução

A soma é (1,11+0,011)×21=10,001×21=1,0001×22=4,25(1,11+0,011)\times2^1=10,001\times2^1=1,0001\times2^2=4,25. O produto é 1,1×1,11=10,1012=1,0101×21=2,6251,1\times1,11=10,101_2=1,0101\times2^1=2,625. Ambos têm expansão curta, cabem exatamente em binary32, sem arredondamento adicional.

Confere a tua resposta:

  • Soma 4,25; produto 2,625.
  • Alinha na soma e normaliza os dois resultados.

Erros frequentes

Não somes expoentes na adição; não conserves significando maior ou igual a 2 sem ajustar o expoente.

Voltar à explicação
Dois empates em binary32

Usa binary32 e arredondamento ao mais próximo, com empates para par. Que valores ficam guardados ao converter os valores exatos 1+2−241+2^{-24} e 1+3×2−241+3\times2^{-24}? Mostra os dois vizinhos de cada valor.

Pista

Os valores exatos estão a meio de dois binary32 consecutivos.

Mais uma pista

O passo entre 1 e 2 é 2−232^{-23}.

Solução

O primeiro fica a meio de 11 e 1+2−231+2^{-23}; escolhemos 1, fração inteira F=0, par. O segundo fica a meio de 1+2−231+2^{-23} e 1+2×2−231+2\times2^{-23}; escolhemos o segundo vizinho, com F=2, par. Portanto os resultados são 11 e 1+2−221+2^{-22}. A regra examina o último bit conservado, não o sinal nem o expoente.

Confere a tua resposta:

  • Primeiro resultado 1; segundo 1+2^-22.
  • Identifica o passo 2^-23 e o bit final par em cada empate.

Erros frequentes

Não arredondes sempre para baixo nem interpretes par como um valor decimal inteiro par.

Voltar à explicação
O bit implícito muda

Descodifica 0x007FFFFF e 0x00800000 em binary32. Qual é a distância entre eles? Explica por que não há um salto grande na passagem de subnormal a normal.

Pista

No primeiro E=0; no segundo E=1.

Mais uma pista

A fórmula do subnormal usa expoente real 1−127=−1261-127=-126.

Solução

007FFFFF tem F=223−12^{23}-1, valor (1−2−23)2−126(1-2^{-23})2^{-126}. 00800000 tem E=1 e F=0, valor 2−1262^{-126}. A diferença é 2−232−126=2−1492^{-23}2^{-126}=2^{-149}, o mesmo passo dos subnormais. Usar um 1 implícito no primeiro código duplicaria aproximadamente o seu valor.

Confere a tua resposta:

  • Maior subnormal (1−2^-23)×2^-126 e menor normal 2^-126.
  • Distância 2^-149; muda o bit implícito e não o passo na fronteira.

Erros frequentes

Não uses E−bias nos subnormais nem compares as palavras como inteiros para obter uma diferença de valores reais.

Voltar à explicação

À tua maneira

Aparência

Modo de cor
Tema
Cor de destaque

Leitura

Fonte de leitura

Álgebra, lógica e uma ideia de cada vez.

Código

Fonte do código

Navegação

Cursor de leitura, sem edição. h, j, k, l movem; / pesquisa nesta página. v seleciona caracteres; V seleciona linhas; y copia. Tab permite destacar ou comentar. Espaço ou Enter abre blocos recolhíveis. Nos cartões, h, j, k, l mudam o foco.

CSS personalizado

Ativa uma sugestão ou guarda o teu CSS. Só muda este navegador.

Usa --page, --text e --accent para acompanhar o tema.

Seletores e recuperação

.site-header, .prose, .course-card, [data-reading-history], [data-playground] e .page-actions.

Abre a aparência com a tecla vírgula ou no rodapé. Se o CSS esconder os controlos, abre esta página sem CSS personalizado.

Pesquisar

Escreve para pesquisar em todo o site.

para escolher · Enter para abrir · Esc para fechar

Copiar fórmula

A cópia automática não está disponível. Copia o LaTeX abaixo.

Pesquisar nesta página

Enter procura · n / N repetem · Esc cancela. Ctrl / Cmd K pesquisa todo o site.

Atalhos de teclado

Clica numa tecla para a mudar. Esc cancela. Backspace desativa.

PesquisarCtrl / Cmd K

Os atalhos não interferem enquanto escreves. Tab e Enter funcionam sempre.