Поки a signed long long int
заповіту не буде A*B
, два з них будуть. Таким чином, A*B
можна розкласти на дерева дерева різні показники, будь-який з них підходить один 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;
Те саме для C*D
.
Простежуючи прямий шлях, віднімання можна зробити кожній парі AB_i
і CD_i
так само, використовуючи додатковий біт перенесення (точно 1-бітове ціле число) для кожної. Отже, якщо ми скажемо E = A * BC * D, ви отримаєте щось на кшталт:
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
...
Продовжуємо, переносячи верхню половину E_10
на E_20
(змініть на 32 та додайте, а потім стерти верхню половину E_10
).
Тепер ви можете позбутися біт-переносника E_11
, додавши його правильним знаком (отриманим від частини, що не переносить) до E_20
. Якщо це викликає переповнення, результат також не підходить.
E_10
тепер має достатньо «місця», щоб забрати верхню половину E_00
(зміщення, додавання, видалення) та біт для перенесення E_01
.
E_10
може бути знову більшим, тому повторюємо передачу на E_20
.
У цей момент E_20
має стати нульовим, інакше результат не підійде. Верхня половинаE_10
порожнього в результаті передачі також порожня.
Останній крок - перевести нижню половину E_20
вE_10
знову.
Якщо очікування, яке E=A*B+C*D
би відповідало signed long long int
трюму, зараз у нас є
E_20=0
E_10=0
E_00=E