Signé & unsigned integer multiplication
En point fixe maths j'ai utiliser beaucoup de 16bit de signaux et d'effectuer une multiplication avec 32 bits de résultats intermédiaires. Par exemple:
int16_t a = 16384; //-1.0q14 or 1.0*2^14
int16_t b = -24576; //-1.4q14 or 1.4*2^14
int16_t c; //result will be q14
c = (int16_t)(((int32_t)a * (int32_t)b)>>14);
Permet de dire que a est un q14 numéro c ont la même échelle que la b.
C'est très bien et fonctionne non signés, ainsi que de l'arithmétique signée.
La question est: Qu'advient-il si je ont été de mélanger les types? Par exemple, si je sais que le coefficient "a" est toujours d'aller à la plage de 0,0 à 1,0, il est tentant d'en faire un unsigned int q15 à obtenir le plus de bits de précision (et de changer le décalage à 15). Cependant, je n'ai jamais compris ce qui se passe si vous essayez de multiplier signés et non signés numéros en C et l'ont évité. En ASM, je ne me souviens pas qu'il y ait un multiplier instruction de travail avec un mélange de types sur n'importe quelle architecture, de sorte que même si C fait la bonne chose, je ne suis pas sûr qu'il pourrait générer un code efficace.
Dois-je continuer ma pratique de ne pas mélanger signé un unsigned types de point fixe code? Ou cela peut-il fonctionner correctement?
Poster une réponse au lieu d'un commentaire afin que je puisse l'accepter 😉
Pour quelque raison, à l'époque, je pensais que je ne faisais que répondre à une partie de votre question, alors je l'ai laissé un commentaire. Maintenant que je regarde à nouveau, je ne sais pas pourquoi j'ai pensé que. Merci!
OriginalL'auteur phkahler | 2013-06-06
Vous devez vous connecter pour publier un commentaire.
Ce post Parle de ce qui se passe lors de la multiplication des entiers signés et non signés. Réponse courte est, aussi longtemps qu'ils sont au même rang (taille), un document signé est implicitement transtypage non signé.
Aussi longtemps que vous comprenez le typecasting règles (quel que soit le langage de programmation), ou d'utiliser des typecasting, et vous avez également de comprendre les implications de typecasting de signé non signé (un nombre négatif va produire, ce qui peut apparaître comme du charabia quand typecasted à une valeur signée), puis il devrait y avoir aucun problème de mélange entiers signés et non signés.
Pouvez-vous éditer votre post ci-dessus avec les valeurs exactes que vous êtes imputation dans a et b, qui viennent avec des résultats qui vont à l'encontre des règles?
OriginalL'auteur Benjamin Leinweber
J'ai eu un problème similaire. Il a causé une violation d'accès d'un crash dans l'
x64
version. Le code parcourt un tampon d'image des lignes de balayage. L'obtention de la prochaine ligne de balayage pointeur va:Négatif foulée moyens de l'itération à partir du bas vers le haut de la ligne de balayage. Le produit
stride * iRow
c'est à diresigned * unsigned
est typecasted àunsigned __int64
avec la valeur4294963972
qui pousse lepNextLine
de mémoire du programme.La même chose arrive avec le
x32
version du programme, mais il n'y a pas de collision. Peut-être parce que lex32
pNextLine
pointeur juste s'enroule autour (mais il reste dans la mémoire du programme).OriginalL'auteur Naum