0
votes

Coulée à virgule fixe 16 à 64 bits?

Macros de conversion de point fixe pour les nombres de 16 bits, avec des valeurs max et min:

#define SCALEFACTOR_16(N) ( 1UL << N )


0 commentaires

3 Réponses :


2
votes

Votre système a 32 bits ( non signé ) int . Tout le travail que vous effectuez est avec des valeurs 32 bits et vous montez après faire le travail. Lorsque vous montez de non signé int à intz_t , il ne modifie pas la valeur (elle n'interprime pas le bit haut d'un non signé comme un bit de signalisation à prolonger), il est donc zéro rempli.


0 commentaires

1
votes

Parce que vous coulez une valeur non signée de 32 bits (0xFFFF 8000) sur une valeur signée de 64 bits (0x0000 0000 FFFF 8000). La coulée d'une valeur non signée sur un type plus large ajoute juste 0 à l'avant. Casting La valeur signée sur un type plus large ajoute le bit de signalisation à l'avant comme:

(int64_t)(int32_t)Q_MIN16; ==> 0xffff ffff ffff 8000


0 commentaires

1
votes

Le 1U code> Les constantes d'entier ont le type non signé INT code>. Le type de résolution d'une opération de décalage est celui de son opérande gauche (favorisé), dans ce cas non signé INT code>.

Effacement des décalages bits sur des types non signés est la bonne voie, mais après le décalage , vous devez reconvertir le type signé. Sinon, la conversion sur intz_t code> ne "signer" pas "étendre" le numéro alors que le compilateur voit un type non signé. P>

Veuillez noter que le -scalefactor_16 est Fishy pour la même raison, cela ne fait rien, car l'opérande du moins est non signé. Lors de la conversion correctement du type non signé en signé, le compilateur gérera le signe automatiquement, il n'y a donc pas besoin de - code>. P>

échecFactor_16 code> a également reçu un bug Vous devez envelopper le paramètre macro entre parenthèses. P>

solution: p> xxx pré>


Vous pouvez facilement faire cette macro assez générique-générique: P>

#include <stdio.h>
#include <stdint.h>
#include <inttypes.h>

#define SCALEFACTOR(N) ( 1U << (N) )
#define Q_MAX(N) ( (int##N##_t)(  SCALEFACTOR(N-1) - 1U ) )
#define Q_MIN(N) ( (int##N##_t)( -SCALEFACTOR(N-1)      ) )

int main (void)
{
  int64_t x;
  x = Q_MIN(16);
  printf("%.16"PRIx64 " %"PRIi64 "\n", x, x);

  x = Q_MIN(32);
  printf("%.16"PRIx64 " %"PRIi64 "\n", x, x);
}


3 commentaires

"Le type résultant d'une opération de décalage est celui de son opérande gauche (promu), dans ce cas non signé INT ". Quel opérant de gauche avez-vous voulu dire est UINT?


@Danijel il n'y a qu'un seul changement. L'opérande gauche de 1u << n est 1u .


Ok, désolé, je pensais que vous faisiez référence à une variable, à gauche du = .