Na computação, o decimal64 é um formato de número de ponto flutuante decimal que ocupa 8 bytes (64 bits) na memória do computador. O formato foi introduzido oficialmente na revisão de 2008 do padrão IEEE 754, também conhecido como ISO/IEC/IEEE 60559:2011.

Formato Os valores decimal64 são categorizados como números normais ou subnormais (denormais) e podem ser codificados nos formatos decimal inteiro binário (BID) ou decimal densamente empacotado (DPD). Valores normais podem possuir uma precisão de 16 dígitos variando de

± 1 , 000000000000000 ×

10

− 383

{\displaystyle \pm 1,000000000000000\times 10^{-383}}

até

± 9 , 999999999999999 ×

10

384

{\displaystyle \pm 9,999999999999999\times 10^{384}}

. Além de números normais e subnormais, o formato também inclui zeros sinalizados, infinitos e NaNs. O formato binário de tamanho idêntico acomoda um espectro que vai do mínimo denormal

± 5 ×

10

− 324

{\displaystyle \pm 5\times 10^{-324}}

, passando pelo mínimo normal com precisão total de 53 bits de

± 2 , 2250738585072014 ×

10

− 308

{\displaystyle \pm 2,2250738585072014\times 10^{-308}}

, até o máximo de

± 1 , 7976931348623157 ×

10

384

{\displaystyle \pm 1,7976931348623157\times 10^{384}}

. Como no IEEE 754 os formatos decimais não são normalizados, a maioria dos valores com menos de 16 dígitos significativos possui múltiplas representações possíveis;

1000000 ×

10

− 2

= 100000 ×

10

− 1

= 10000 ×

10

0

= 1000 ×

10

1

{\displaystyle 1000000\times 10^{-2}=100000\times 10^{-1}=10000\times 10^{0}=1000\times 10^{1}}

têm todos o mesmo valor de 10000. Esses conjuntos de representações para um mesmo valor são chamados de coortes. Os diferentes membros podem ser usados para indicar quantos dígitos do valor são conhecidos com precisão. Cada zero sinalizado possui 768 representações possíveis (1536 para todos os zeros, em duas coortes diferentes).

Codificação de valores decimal64

O IEEE 754 permite duas codificações alternativas para valores decimal64. O padrão não especifica como sinalizar qual representação está sendo usada, por exemplo, em uma situação onde valores decimal64 são transmitidos entre sistemas:

Na codificação binária, baseada no formato Decimal inteiro binário (BID), o significando de 16 dígitos é representado como um inteiro positivo codificado em binário. Na codificação decimal, baseada no formato Decimal densamente empacotado (DPD), o significando de 16 dígitos é representado como um inteiro positivo codificado em decimal, com 5 grupos de 3 dígitos cada, representados em declets (sequências de 10 bits). O bit mais significativo é codificado separadamente. Isso é eficiente porque

2

10

= 1024

{\displaystyle 2^{10}=1024}

é apenas um pouco maior do que o necessário para conter todos os inteiros de 0 a 999. Ambas as alternativas fornecem exatamente o mesmo conjunto de números representáveis: 16 dígitos de significando e

3 ×

2

8

= 768

{\displaystyle 3\times 2^{8}=768}

valores de expoente decimal possíveis. Todos os valores de expoente decimal armazenáveis em um número binary64 são representáveis no decimal64, e a maioria dos bits do significando de um binary64 são armazenados mantendo aproximadamente o mesmo número de dígitos decimais no significando. Em ambos os casos, os 4 bits mais significativos do significando, que possuem apenas 10 valores possíveis, são combinados com dois bits do expoente (3 valores possíveis) para usar 30 dos 32 valores possíveis de um campo de 5 bits. As combinações restantes codificam infinitos e NaNs. BID e DPD usam bits diferentes para o campo de combinação. Para Infinito e NaN, todos os outros bits da codificação não são usados. Sendo assim, uma matriz pode ser preenchida com um único valor de byte para defini-la como Infinitos ou NaNs.

Campo de significando decimal inteiro binário (BID) Este formato usa um significando binário de 0 a

10

16

− 1 = 9999999999999999 = 2386

F

26

FC

0

FFFF

16

=

1000111100001101111001001101111110000001111111111111111111111111

2

{\displaystyle 10^{16}-1=9999999999999999=2386{\text{F}}26{\text{FC}}0{\text{FFFF}}_{16}=1000111100001101111001001101111110000001111111111111111111111111_{2}}

. A codificação, completamente armazenada em 64 bits, pode representar significandos binários de até

10 ×

2

50

− 1 = 11258999068426239 = 27

FFFFFFFFFFFF

16

{\displaystyle 10\times 2^{50}-1=11258999068426239=27{\text{FFFFFFFFFFFF}}_{16}}

, mas valores maiores que

10

16

− 1

{\displaystyle 10^{16}-1}

são ilegais e o padrão exige que as implementações os tratem como 0 se forem encontrados na entrada. Como descrito acima, a codificação varia dependendo se os 4 bits mais significativos do significando estão na faixa de 0 a 7 (

0000

2

{\displaystyle 0000_{2}}

a

0111

2

{\displaystyle 0111_{2}}

), ou superior (

1000

2

{\displaystyle 1000_{2}}

ou

1001

2

{\displaystyle 1001_{2}}

). Se os dois bits após o bit de sinal forem "00", "01" ou "10", então o campo do expoente consiste nos 10 bits seguintes ao bit de sinal e o significando ocupa os 53 bits restantes com um bit 0 condutor implícito. Isto inclui números subnormais onde o dígito condutor do significando é 0. Se os dois bits após o bit de sinal forem "11", então o campo do expoente de 10 bits é deslocado 2 bits para a direita (após o bit de sinal e os bits "11" subsequentes) e o significando representado fica nos 51 bits restantes. Neste caso, há uma sequência condutora implícita (ou seja, não armazenada) de 3 bits "100" para os bits mais significativos do significando verdadeiro.

Os bits condutores do campo de significando não codificam o dígito decimal mais significativo; eles são simplesmente parte de um número binário puro maior. Por exemplo, um significando de 8000000000000000 é codificado como o binário

0111000110101111110101001001100011010000000000000000000000000000

2

{\displaystyle 0111000110101111110101001001100011010000000000000000000000000000_{2}}

com os 4 bits condutores codificando 7; o primeiro significando que requer um 54o bit é

2

53

= 9007199254740992

{\displaystyle 2^{53}=9007199254740992}

. O maior significando válido é 9999999999999999 cuja codificação binária é

( 100 )

011100011011110010011011111100000011111111111111111111111111

2

{\displaystyle (100)011100011011110010011011111100000011111111111111111111111111_{2}}

(com os 3 bits mais significativos (100) não armazenados, mas implícitos como mostrado acima; e o próximo bit é sempre zero nas codificações válidas). Nos casos acima, o valor representado é:

( − 1

)

sign

×

10

exponent

− 398

×

significand

{\displaystyle (-1)^{\text{sign}}\times 10^{{\text{exponent}}-398}\times {\text{significand}}}

Se os quatro bits após o bit de sinal forem "1111", então o valor é um infinito ou um NaN, conforme descrito acima:

0 11110 xx...x +infinito 1 11110 xx...x -infinito x 11111 0x...x um NaN quieto x 11111 1x...x um NaN sinalizador

Campo de significando decimal densamente empacotado (DPD) Nesta versão, o significando é armazenado como uma série de dígitos decimais. O dígito condutor está entre 0 e 9 (3 ou 4 bits binários) e o restante do significando usa a codificação decimal densamente empacotado (DPD). Os 2 bits condutores do expoente e o dígito condutor (3 ou 4 bits) do significando são combinados nos cinco bits que seguem o bit de sinal. Os oito bits seguintes formam o campo de continuação do expoente, fornecendo os bits menos significativos do expoente. Os últimos 50 bits formam o campo de continuação do significando, que consiste em cinco declets de 10 bits. Cada declet codifica três dígitos decimais usando a codificação DPD. Se os dois primeiros bits após o bit de sinal forem "00", "01" ou "10", eles representam os bits condutores do expoente, enquanto os três bits subsequentes "cde" são considerados como o dígito decimal condutor (variando de 0 a 7). Se os dois primeiros bits após o bit de sinal forem "11", então os dois bits seguintes são os bits condutores do expoente, e o bit seguinte "e" é prefixado com os bits implícitos "100" para formar o dígito decimal condutor (8 ou 9). As duas combinações restantes (11 110 e 11 111) do campo de 5 bits após o bit de sinal são usadas para representar ±infinito e NaNs, respectivamente.

A conversão DPD para BCD de 3 dígitos para os declets é fornecida pela tabela a seguir. b9...b0 são os bits do DPD, e d2...d0 são os três dígitos BCD. Os 8 valores decimais cujos dígitos são todos 8s ou 9s possuem quatro codificações cada. Os bits marcados com x na tabela acima são ignorados na entrada, mas sempre serão 0 nos resultados calculados. As 24 codificações não padronizadas preenchem a lacuna entre

10

3

= 1000

{\displaystyle 10^{3}=1000}

e

2

10

= 1024

{\displaystyle 2^{10}=1024}

. Nos casos acima, com o significando verdadeiro como a sequência de dígitos decimais decodificados, o valor representado é:

( − 1

)

bitdesinal

×

10

bitsdoexpoente

2

398

10

×

significandoverdadeiro

10

{\displaystyle (-1)^{\text{bitdesinal}}\times 10^{{\text{bitsdoexpoente}}_{2}-398_{10}}\times {\text{significandoverdadeiro}}_{10}}

Implementações Existem múltiplas bibliotecas disponíveis para cálculos com tipos de dados decimais. Alguns exemplos são listados abaixo:

O libdfp implementa o Relatório Técnico ISO/IEC "ISO/IEC TR 24732". A biblioteca implementa funções matemáticas para ambientes construídos com o gcc e glibc. Ela usa tipos decimais IEEE 754 codificados em BID, com a possibilidade de alternar para o formato de ponto flutuante decimal64 através da recompilação do gcc. A Intel Decimal Floating-Point Math Library é uma biblioteca em C que implementa a especificação de aritmética de ponto flutuante decimal IEEE 754-2008 tratando os tipos decimais como elementos UINTxx chamados de decimalxx. A biblioteca melhora o desempenho calculando funções mais intrincadas em binário sempre que possível, mas isso introduz alguns erros de arredondamento binário em cálculos decimais. O decNumber fornece tipos de dados e funções para calcular valores usando ponto flutuante decimal com precisão arbitrária. Ele apresenta a opção de definir os parâmetros compatíveis com IEEE 754 decSingle, decDouble e decSingle. Ele realiza conversões eficientes entre números decimais e strings. O Mpdecimal é uma implementação da *Especificação Geral de Aritmética Decimal* proposta por Mike Cowlishaw, com a opção de definir parâmetros compatíveis com os tipos IEEE. Ele fornece precisão arbitrária, usando um inteiro de 8 bits para codificar sinalizadores de runtime e o sinal do número. A biblioteca representa números usando sete ou mais palavras duplas ou quádruplas, armazenando o expoente com sinal, os dígitos, o comprimento em palavras, as palavras alocadas, um ponteiro para data e o próprio data. O data é armazenado como um array de duas ou mais palavras, que mantém o coeficiente em elementos de 32 bits (9 dígitos) ou 64 bits (19 dígitos). Ele é implementado em Python como o módulo decimal.

Veja também Formato de ponto flutuante bfloat16 Formato de ponto flutuante de precisão quádrupla Formato de ponto flutuante de meia precisão

Referências