multiplication de points fixes sans temporaire 64 bits

Bonjour, je suis en train d’implémenter des calculs mathématiques en virgule fixe pour les systèmes embarqués et j’essaie de multiplier deux nombres de 16,16 points fixes sans créer de fichier temporaire à 64 bits. Jusqu’ici, voici le code que j’ai créé et qui génère le moins d’instructions.

int multiply(int x, int y){ int result; long long temp = x; temp *= y; temp >>= 16; result = temp; return result; } 

Le problème avec ce code est qu’il utilise un entier temporaire de 64 bits qui semble générer un code assembleur incorrect. J’essaie de faire un système qui utilise deux entiers 32 bits au lieu d’un 64 bits. Quelqu’un sait-il comment faire ça?

    Pensez à vos numéros comme chacun composé de deux grands “chiffres”.

      AB x CD 

    La “base” des chiffres est la largeur de 2 ^ bit, c’est-à-dire 2 ^ 16 ou 65536.

    Donc, le produit est

     D*B + D*A*65536 + C*B*65536 + C*A*65536*65536 

    Cependant, pour que le produit soit correctement déplacé de 16, vous devez diviser tous ces termes par 65536, donc

     D*B/65536 + D*A + C*B + C*A*65536 

    En C:

     uint16_t a = x >> 16; uint16_t b = x & 0xffff; uint16_t c = y >> 16; uint16_t d = y & 0xffff; return ((d * b) >> 16) + (d * a) + (c * b) + ((c * a) << 16); 

    La version signée est un peu plus compliquée; Il est souvent plus facile d'effectuer l'arithmétique sur les valeurs absolues de x et y , puis de fixer le signe (sauf en cas de débordement, que vous pouvez vérifier de manière fastidieuse).