Même si un signed long long int
ne tiendra pas A*B
, deux d'entre eux le feront. Ainsi A*B
pourrait être décomposé en termes d'arbre d'exposant différent, chacun d'entre eux convenant à un signed long long int
.
A1=A>>32;
A0=A & 0xffffffff;
B1=B>>32;
B0=B & 0xffffffff;
AB_0=A0*B0;
AB_1=A0*B1+A1*B0;
AB_2=A1*B1;
Pareil pour C*D
.
En suivant la voie directe, la sous-action pourrait être effectuée sur chaque paire de AB_i
et de CD_i
même, en utilisant un bit de report supplémentaire (exactement un entier de 1 bit) pour chacun. Donc, si nous disons E = A * BC * D, vous obtenez quelque chose comme:
E_00=AB_0-CD_0
E_01=(AB_0 > CD_0) == (AB_0 - CD_0 < 0) ? 0 : 1 // carry bit if overflow
E_10=AB_1-CD_1
...
On continue en transférant la moitié supérieure de E_10
à E_20
(décaler de 32 et ajouter, puis effacer la moitié supérieure de E_10
).
Vous pouvez maintenant vous débarrasser du bit de retenue E_11
en l'ajoutant avec le bon signe (obtenu à partir de la partie non-retenue) à E_20
. Si cela déclenche un débordement, le résultat ne conviendra pas non plus.
E_10
a maintenant assez d'espace pour prendre la moitié supérieure de E_00
(décalage, ajouter, effacer) et le bit de report E_01
.
E_10
peut être plus grand maintenant, nous répétons donc le transfert vers E_20
.
À ce stade, E_20
doit devenir zéro, sinon le résultat ne correspondra pas. La moitié supérieure deE_10
est également vide suite au transfert.
La dernière étape consiste à transférer la moitié inférieure de E_20
à E_10
nouveau.
Si l'attente qui E=A*B+C*D
conviendrait aux signed long long int
prises, nous avons maintenant
E_20=0
E_10=0
E_00=E