2017-06-11 4 views
0

J'implémente l'arithmétique en virgule fixe à l'aide des diapositives [1]. Tout fonctionne comme il se doit ma question est les diapositives liées, aussi chaque ressource que je lis dit en multipliant et en divisant les nombres de points fixes il y a un bon changement qu'ils débordent. Donc, ils suggèrent de les mouler à une plus grande taille pour les multiplier puis les rejeter. Comme,Traitement de dépassement en arithmétique de point fixe

(INT32)(((INT64)a * 
     (INT64)b) >> N) 

au lieu de juste,

((a * b) >> N) 

Cela fonctionne pour 8,16,32 entiers de bits, mais comment puis-je gérer le débordement 64 bits entier? Il n'y a pas de type int 128 bits (AFAIK gcc a des entiers 128 bits mais ils ne sont pas portables.)

Je voudrais aussi via le constructeur auto calculer les bits requis pour l'epsilon fourni par l'utilisateur (précision minimale requise)

Si une précision de 0,01 est requise, 6 bits suffisent pour N. (Puisque 1/64 = 0,015) Je ne pouvais pas comprendre la logique de conversion de la précision en bits requis?

[1] http://jet.ro/files/The_neglected_art_of_Fixed_Point_arithmetic_20060913.pdf

+0

Pour convertir la précision aux bits requis, vous pouvez utiliser une formule mathématique simple. 'floor (log (1.0/required_accuracy)/log (2))' –

+0

Implémenter [la multiplication longue] (https://en.wikipedia.org/wiki/Multiplication_algorithm#Long_multiplication). Rappelez-vous comment, à l'école primaire, vous pourriez multiplier les nombres décimaux à deux chiffres en utilisant seulement une table de multiplication à un chiffre. –

+0

Une multiplication longue, comme le dit Igor ... mais un point fixe de 64 bits n'est pas très utile, donc vous n'avez probablement pas besoin de vous embêter avec ça. –

Répondre

0

bien vous pouvez la chaîne 64 bits ops pour produire N * 64 opérations de bits. Avec +,- il est simple O(n) empilage. Pour *,^2 vous pouvez utiliser Karatsuba pour plus d'informations voir liées AQ s:

Division également est possible en utilisant des séparateurs comme celui-ci (ou tout autre approximation):

Pour plus d'informations, vous pouvez consulter le code source de tout bigint/lib BigDecimal là-bas.

Une autre façon de traiter avec dépassement haut/bas est ceci: