Q (format numérique) - Q (number format)

La notation Q est un moyen succinct de spécifier les paramètres d'un format de nombre à virgule fixe binaire . Un certain nombre d' autres notations ont été utilisées dans le même but.

Définition

Version Texas Instruments

La notation Q, telle que définie par Texas Instruments, se compose de la lettre Qsuivie d'une paire de nombres m .n , où m est le nombre de bits utilisés pour la partie entière de la valeur et n est le nombre de bits de fraction.

Par défaut, la notation décrit le format à virgule fixe binaire signé , l'entier non mis à l'échelle étant stocké au format complément à deux , utilisé dans la plupart des processeurs binaires. Le premier bit donne toujours le signe de la valeur (1 = négatif, 0 = non négatif), et il n'est pas compté dans le paramètre m . Ainsi le nombre total w de bits utilisés est 1 + m + n .

Par exemple, la spécification Q3.12décrit un nombre à virgule fixe binaire signé avec un w = 16 bits au total, comprenant le bit de signe, trois bits pour la partie entière et 12 bits qui sont supposés être des fractions. C'est-à-dire un entier signé (complément à deux) de 16 bits, qui est implicitement multiplié par le facteur d'échelle 2 -12

En particulier, lorsque n est égal à zéro, les nombres ne sont que des entiers – . Si m vaut zéro, tous les bits à l'exception du bit de signe sont des bits de fraction ; alors la plage du nombre stocké est de -1,0 (inclus) à +1 (exclusif). Les deux m et n peuvent être négatives

Le m et le point peuvent être omis, auquel cas ils sont déduits de la taille de la variable ou du registre où la valeur est stockée. Cela Q12signifie donc un entier signé avec un nombre quelconque de bits, qui est implicitement multiplié par 2 -12 .

La lettre Upeut être précédée du préfixe pour Qindiquer un format à virgule fixe binaire non signé . Par exemple, UQ1.15décrit des valeurs représentées sous forme d'entiers 16 bits non signés avec un facteur de mise à l'échelle implicite de 2 -15 , qui vont de 0,0 à (2 16 -1)/2 15 = +1,999969482421875.

Version AMD

Une variante de la notation Q a été utilisée par AMD . Dans cette variante, le nombre m comprend le bit de signe. Par exemple, un entier signé de 16 bits serait indiqué Q15.0dans la variante TI, mais Q16.0dans la variante AMD.

Les caractéristiques

La résolution (différence entre des valeurs successives) d'un Q m . n ou UQ m . n format (les deux ont utilisé la convention AMD) est toujours 2 n . La plage des valeurs représentables est

  • −2 m −1 à +2 m −1 − 2 n pour le format signé, et
  • 0 à 2 m − 2 n pour le format non signé.

Par exemple, un nombre au format Q15.1 nécessite 15+1 = 16 bits, a une résolution de 2 -1 = 0,5 et les valeurs représentables vont de -2 14 = -16384,0 à +2 14 - 2 -1 = +16383,5. En hexadécimal, les valeurs négatives vont de 0x8000 à 0xFFFF suivies des non négatives de 0x0000 à 0x7FFF.

Opérations mathématiques

Les nombres Q sont un rapport de deux entiers : le numérateur est conservé en mémoire, le dénominateur est égal à 2 n .

Considérez l'exemple suivant :

  • Le dénominateur Q8 est égal à 2 8 = 256
  • 1,5 est égal à 384/256
  • 384 est stocké, 256 est déduit car il s'agit d'un nombre Q8.

Si la base du nombre Q doit être maintenue ( n reste constant), les opérations mathématiques du nombre Q doivent maintenir le dénominateur constant. Les formules suivantes montrent des opérations mathématiques sur les nombres Q généraux et .

Parce que le dénominateur est une puissance de deux, la multiplication peut être implémentée comme un décalage arithmétique vers la gauche et la division comme un décalage arithmétique vers la droite ; sur de nombreux processeurs, les décalages sont plus rapides que la multiplication et la division.

Pour maintenir la précision, les résultats intermédiaires de multiplication et de division doivent être à double précision et il faut prendre soin d' arrondir le résultat intermédiaire avant de le reconvertir au nombre Q souhaité.

En utilisant C, les opérations sont (notez qu'ici, Q fait référence au nombre de bits de la partie fractionnaire) :

Une addition

int16_t q_add(int16_t a, int16_t b)
{
    return a + b;
}

Avec saturation

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;
}

Contrairement à la virgule flottante ±Inf, les résultats saturés ne sont pas collants et ne satureront pas en ajoutant une valeur négative à une valeur saturée positive (0x7FFF) et vice versa dans cette implémentation illustrée. En langage assembleur, l'indicateur Signed Overflow peut être utilisé pour éviter les transtypages nécessaires pour cette implémentation C.

Soustraction

int16_t q_sub(int16_t a, int16_t b)
{
    return a - b;
}

Multiplication

// 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;
}

Division

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);
}

Voir également

Les références

Lectures complémentaires

Liens externes