A notação Q é uma forma de especificar os parâmetros de um formato de número binário em ponto fixo. Especificamente, ela determina quantos bits são alocados para a parte inteira, quantos para a parte fracionária e se existe um bit de sinal. Por exemplo, na notação Q, Q7.8 significa que os números em ponto fixo sinalizados neste formato possuem 7 bits para a parte inteira e 8 bits para a parte fracionária. Um bit extra é adicionado implicitamente para números sinalizados. Portanto, Q7.8 forma uma palavra de 16 bits, com o bit mais significativo representando o bit de sinal em Complemento para dois.
Existe uma variação da notação Q da ARM que adiciona explicitamente o bit de sinal à parte inteira. Na notação Q da ARM, o formato acima seria chamado de Q8.8. Várias outras notações têm sido usadas para o mesmo propósito.
Definição
Formato Geral
U
⏟
s e m
s i n a l
Q
m ⏟
i n t e i r o
.
n ⏟
f r a c
a ~
o
{\displaystyle \underbrace {\mathrm {U} } _{\mathrm {\scriptscriptstyle sem\;sinal} }\;\mathbf {Q} \;\underbrace {m} _{\mathrm {\scriptscriptstyle inteiro} }\;\;\mathbf {.} \;\underbrace {n} _{\mathrm {\scriptscriptstyle frac{\tilde {a}}o} }}
Versão da Texas Instruments A notação Q, conforme definida pela Texas Instruments, consiste na letra Q seguida por um par de números m.n, onde m é o número de bits usados para a parte inteira do valor, e n é o número de bits da fração. Por padrão, a notação descreve um formato de ponto fixo binário sinalizado, com o inteiro não dimensionado sendo armazenado no formato de Complemento para dois, utilizado na maioria dos processadores binários. Sendo assim, o primeiro bit sempre indica o sinal do valor (1 = negativo, 0 = não negativo), e ele não é contado no parâmetro m. Dessa forma, o número total w de bits utilizados é 1 + m + n. Por exemplo, a especificação Q3.12 descreve um número em ponto fixo binário sinalizado com tamanho de palavra w = 16 bits no total, compreendendo o bit de sinal, três bits para a parte inteira e 12 bits para a fração. Isso pode ser visto como um inteiro sinalizado de 16 bits (complemento para dois) que é multiplicado implicitamente pelo fator de escala
2
− 12
{\displaystyle 2^{-12}}
. In particular, quando n é zero, os números são apenas inteiros. Se m é zero, todos os bits exceto o bit de sinal são bits fracionários; então, o intervalo do número armazenado vai de −1.0 (inclusivo) a +1.0 (exclusivo). O m e o ponto podem ser omitidos, caso em que são inferidos a partir do tamanho da variável ou registrador onde o valor é armazenado. Assim, Q12 significa um inteiro sinalizado com qualquer número de bits, que é multiplicado implicitamente por
2
− 12
{\displaystyle 2^{-12}}
. A letra U pode ser prefixada ao Q para denotar um formato de ponto fixo binário sem sinal. Por exemplo, UQ1.15 descreve valores representados como inteiros não sinalizados de 16 bits com um fator de escala implícito de
2
− 15
{\displaystyle 2^{-15}}
, variando de
0.0
{\displaystyle 0.0}
a
(
2
16
− 1 )
/
2
15
= + 1.999969482421875
{\displaystyle (2^{16}-1)/2^{15}=+1.999969482421875}
.
Versão da ARM Uma variante da notação Q tem sido usada pela ARM, na qual o número m também conta o bit de sinal. Por exemplo, um inteiro sinalizado de 16 bits que a variante da TI denota como Q15.0, seria Q16.0 na variante da ARM. Os números sem sinal são idênticos em ambas as variantes. Embora tecnicamente o bit de sinal pertença tanto à parte fracionária quanto à parte inteira, a notação da ARM tem o benefício de não possuir bits implícitos, de modo que o tamanho da palavra é sempre
m + n
bits
{\displaystyle m+n\ {\text{bits}}}
.
Características A resolução (diferença entre valores sucessivos) de um formato Qm.n ou UQm.n é sempre 2−n. O intervalo de valores representáveis depende da notação utilizada:
Por exemplo, um número no formato Q14.1 requer 14+1+1 = 16 bits, possui resolução 2−1 = 0.5, e os valores representáveis variam de −214 = −16384.0 a +214 − 2−1 = +16383.5. Em hexadecimal, os valores negativos variam de 0x8000 a 0xFFFF, seguidos pelos valores não negativos de 0x0000 a 0x7FFF.
Operações matemáticas Os números Q são uma razão de dois inteiros: o numerador é mantido no armazenamento, e o denominador
d
{\displaystyle d}
é igual a 2n. Considere o seguinte exemplo:
O denominador Q8 é igual a 28 = 256 1.5 é igual a 384/256 384 é armazenado, 256 é inferido porque se trata de um número Q8. Se a base do número Q deve ser mantida (n permanece constante), as operações matemáticas do número Q devem manter o denominador
d
{\displaystyle d}
constante. As fórmulas a seguir mostram as operações matemáticas nos números Q gerais
N
1
{\displaystyle N_{1}}
e
N
2
{\displaystyle N_{2}}
.
N
1
d
+
N
2
d
=
N
1
+
N
2
d
N
1
d
−
N
2
d
=
N
1
−
N
2
d
(
N
1
d
×
N
2
d
)
× d
=
N
1
×
N
2
d
(
N
1
d
/
N
2
d
)
/
d
=
N
1
/
N
2
d
{\displaystyle {\begin{aligned}{\frac {N_{1}}{d}}+{\frac {N_{2}}{d}}&={\frac {N_{1}+N_{2}}{d}}\\{\frac {N_{1}}{d}}-{\frac {N_{2}}{d}}&={\frac {N_{1}-N_{2}}{d}}\\\left({\frac {N_{1}}{d}}\times {\frac {N_{2}}{d}}\right)\times d&={\frac {N_{1}\times N_{2}}{d}}\\\left({\frac {N_{1}}{d}}/{\frac {N_{2}}{d}}\right)/d&={\frac {N_{1}/N_{2}}{d}}\end{aligned}}}
Como o denominador é uma potência de dois, a multiplicação pode ser implementada como um deslocamento aritmético para a esquerda e a divisão como um deslocamento aritmético para a direita; em muitos processadores, os deslocamentos são mais rápidos do que a multiplicação e a divisão. Para manter a precisão, os resultados intermediários de multiplicação e divisão devem ser de precisão dupla, e deve-se tomar cuidado no arredondamento do resultado intermediário antes de convertê-lo de volta para o número Q desejado. Usando a linguagem C, as operações são (note que aqui, Q refere-se ao número de bits da parte fracionária):
Adição
Com saturação
Ao contrário do ±Inf de ponto flutuante, os resultados saturados não são persistentes e perderão a saturação ao adicionar um valor negativo a um valor saturado positivo (0x7FFF) e vice-versa na implementação mostrada. Em linguagem de montagem, o sinalizador de estouro com sinal pode ser usado para evitar as conversões de tipo necessárias para essa implementação em C.
Subtração
Multiplicação
Divisão
Veja também Estouro de inteiro Aritmética de ponto flutuante
Referências
Leitura adicional Oberstar, Erick L. (30 de agosto de 2007). «Fixed Point Representation & Fractional Math» (PDF). Oberstar Consulting
Ligações externas «Q-Number-Format Java Implementation». GitHub «Q-format Converter» «Q Library (C implementation)». GitHub