Enquanto um signed long long int
não aguentar A*B
, dois deles o farão. Assim, A*B
poderia ser decomposto em termos de árvore de diferentes expoentes, qualquer um deles adequado 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;
O mesmo para C*D
.
Seguindo da maneira correta, a sub-ação poderia ser feita para todos os pares de, AB_i
e da CD_i
mesma forma, usando um bit de transporte adicional (com precisão um número inteiro de 1 bit) para cada um. Então, se dissermos E = A * BC * D, você terá algo como:
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
...
Continuamos transferindo a metade superior de E_10
para E_20
(mude 32 e adicione e depois apague a metade superior E_10
).
Agora você pode se livrar do bit de transporte E_11
, adicionando-o com o sinal correto (obtido da parte de não transporte) a E_20
. Se isso disparar um estouro, o resultado também não seria adequado.
E_10
agora tem 'espaço' suficiente para retirar a metade superior E_00
(mudar, adicionar, apagar) e o bit de transporte E_01
.
E_10
agora pode ser maior novamente, então repetimos a transferência para E_20
.
Neste ponto, E_20
deve se tornar zero, caso contrário, o resultado não será adequado. A metade superior também E_10
está vazia como resultado da transferência.
O passo final é transferir a metade inferior E_20
para E_10
novamente.
Se a expectativa que E=A*B+C*D
caberia nos signed long long int
porões, agora temos
E_20=0
E_10=0
E_00=E