Podczas gdy jeden signed long long intnie wytrzyma A*B, dwóch z nich to zrobi. A*BMożna więc rozłożyć na trzy wyrażenia o różnych wykładnikach, z których każdy pasuje do jednego 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;
To samo dotyczy C*D .
Idąc prostą drogą, można było dokonać subrakcji na każdej parze AB_ii CD_ipodobnie, używając dodatkowego bitu przenoszenia (dokładnie 1-bitowej liczby całkowitej) dla każdej. Więc jeśli powiemy E = A * BC * D, otrzymasz coś takiego:
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
...
Kontynuujemy, przenosząc górną połowę E_10do E_20(przesuń o 32 i dodaj, a następnie usuń górną połowę E_10).
Teraz możesz pozbyć się bitu przenoszonego E_11, dodając go z odpowiednim znakiem (uzyskanym z części nienoszonej) do E_20. Jeśli spowoduje to przepełnienie, wynik również nie będzie pasował.
E_10teraz ma wystarczająco dużo miejsca, aby wziąć górną połowę z E_00 (przesuń, dodaj, wymaż) i przenoszoną część E_01.
E_10może być teraz ponownie większy, więc powtarzamy transfer do E_20.
W tym momencie E_20musi wynosić zero, w przeciwnym razie wynik nie będzie pasował. W górnej połowieE_10 jest również pusta w wyniku przeniesienia.
Ostatnim krokiem jest ponowne przeniesienie dolnej połowy E_20do E_10.
Jeśli oczekiwanie, E=A*B+C*Dktóre pasowałoby do signed long long intblokad, mamy teraz
E_20=0
E_10=0
E_00=E