Q (formato de número) - Q (number format)
A notação Q é uma maneira sucinta de especificar os parâmetros de um formato de número de ponto fixo binário . Uma série de outras notações foram usadas para o mesmo propósito.
Definição
Versão 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 en é o número de bits de fração.
Por padrão, a notação descreve assinado formato binário ponto fixo, com o inteiro fora de escala a ser armazenado em dois complemento formato, usado na maioria dos processadores binários. O primeiro bit sempre dá o sinal do valor (1 = negativo, 0 = não negativo), e que é não contadas no m parâmetro. Assim, o número total w de bits usados é 1 + m + n .
Por exemplo, a especificação Q3.12
descreve um número de ponto fixo binário com sinal com w = 16 bits no total, compreendendo o bit de sinal, três bits para a parte inteira e 12 bits que são considerados fração. Ou seja, um inteiro assinado de 16 bits (complemento de dois), que é implicitamente multiplicado pelo fator de escala 2 −12
Em particular, quando n é zero, os números são apenas inteiros -. Se m for zero, todos os bits, exceto o bit de sinal, são bits de fração; então, o intervalo do número armazenado é de -1,0 (inclusivo) a +1 (exclusivo). Ambos m e n podem ser negativos
O meo ponto podem ser omitidos, caso em que são inferidos a partir do tamanho da variável ou registro onde o valor está armazenado. Portanto, Q12
significa um inteiro com sinal com qualquer número de bits, que é implicitamente multiplicado por 2 −12 .
A letra U
pode ser prefixada a Q
para denotar um formato de ponto fixo binário sem sinal . Por exemplo, UQ1.15
descreve valores representados como inteiros de 16 bits sem sinal com fator de escala implícito de 2 −15 , que varia de 0,0 a (2 16 -1) / 2 15 = +1,999969482421875.
Versão AMD
Uma variante da notação Q tem sido usada pela AMD . Nesta variante, o número m inclui o bit de sinal. Por exemplo, um inteiro assinado de 16 bits seria denotado Q15.0
na variante TI, mas Q16.0
na variante AMD.
Características
A resolução (diferença entre valores sucessivos) de um Q m . n ou UQ m . O formato n (ambos usaram a convenção AMD) é sempre 2 - n . O intervalo de valores representáveis é
- −2 m −1 a +2 m −1 - 2 - n para formato assinado, e
- 0 a 2 m - 2 - n para o formato sem sinal.
Por exemplo, um número de formato Q15.1 requer 15 + 1 = 16 bits, tem resolução 2 −1 = 0,5 e os valores representáveis variam de -2 14 = -16384,0 a +2 14 - 2 −1 = +16383,5. Em hexadecimal, os valores negativos variam de 0x8000 a 0xFFFF seguidos pelos não negativos de 0x0000 a 0x7FFF.
Operações matemáticas
Os números Q são uma proporção de dois inteiros: o numerador é mantido no armazenamento, o denominador é igual a 2 n .
Considere o seguinte exemplo:
- O denominador Q8 é igual a 2 8 = 256
- 1,5 é igual a 384/256
- 384 é armazenado, 256 é inferido porque é 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 constante. As fórmulas a seguir mostram operações matemáticas nos números Q gerais e .
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, as mudanças são mais rápidas do que a multiplicação e a divisão.
Para manter a precisão, os resultados intermediários da multiplicação e divisão devem ter precisão dupla e deve-se tomar cuidado ao arredondar o resultado intermediário antes de convertê-lo de volta ao número Q desejado.
Usando C, as operações são (observe que aqui, Q se refere ao número de bits da parte fracionária):
Adição
int16_t q_add(int16_t a, int16_t b)
{
return a + b;
}
Com saturação
int16_t q_add_sat(int16_t a, int16_t b)
{
int16_t result;
int32_t tmp;
tmp = (int32_t)a + (int32_t)b;
if (tmp > 0x7FFF)
tmp = 0x7FFF;
if (tmp < -1 * 0x8000)
tmp = -1 * 0x8000;
result = (int16_t)tmp;
return result;
}
Ao contrário do ponto flutuante ± Inf, os resultados saturados não são pegajosos e não ficarão saturados ao adicionar um valor negativo a um valor saturado positivo (0x7FFF) e vice-versa na implementação mostrada. Em linguagem assembly, o sinalizador Signed Overflow pode ser usado para evitar as previsões de tipos necessárias para essa implementação C.
Subtração
int16_t q_sub(int16_t a, int16_t b)
{
return a - b;
}
Multiplicação
// precomputed value:
#define K (1 << (Q - 1))
// saturate to range of int16_t
int16_t sat16(int32_t x)
{
if (x > 0x7FFF) return 0x7FFF;
else if (x < -0x8000) return -0x8000;
else return (int16_t)x;
}
int16_t q_mul(int16_t a, int16_t b)
{
int16_t result;
int32_t temp;
temp = (int32_t)a * (int32_t)b; // result type is operand's type
// Rounding; mid values are rounded up
temp += K;
// Correct by dividing by base and saturate result
result = sat16(temp >> Q);
return result;
}
Divisão
int16_t q_div(int16_t a, int16_t b)
{
/* pre-multiply by the base (Upscale to Q16 so that the result will be in Q8 format) */
int32_t temp = (int32_t)a << Q;
/* Rounding: mid values are rounded up (down for negative values). */
/* OR compare most significant bits i.e. if (((temp >> 31) & 1) == ((b >> 15) & 1)) */
if ((temp >= 0 && b >= 0) || (temp < 0 && b < 0)) {
temp += b / 2; /* OR shift 1 bit i.e. temp += (b >> 1); */
} else {
temp -= b / 2; /* OR shift 1 bit i.e. temp -= (b >> 1); */
}
return (int16_t)(temp / b);
}
Veja também
Referências
Leitura adicional
- Oberstar, Erick L. (2007-08-30) [2004]. "Representação de ponto fixo e matemática fracionária" (PDF) . 1.2. Oberstar Consulting. Arquivado (PDF) do original em 04-11-2017 . Página visitada em 04-11-2017 . (Observação: a precisão do artigo está em disputa; consulte a discussão.)
links externos
- "Implementação de Q-Number-Format Java" . Arquivado do original em 04-11-2017 . Página visitada em 04-11-2017 .
- "Conversor de formato Q" . Arquivado do original em 2021-06-25 . Recuperado em 2021-06-25 .