Если я правильно понял, вы застряли в точке, где вам действительно нужно выполнить 64-битную арифметику, верно?
Если вы выполняете типичное двоичное длинное умножение со сдвигом и сложением, вы можете создать некоторые 64-битные примитивы сдвига и сложения из 32-битных операций, а затем использовать тот же метод.
Вот несколько примеров в виде фрагментов Си (их легко перевести на MIPS, если это то, что вы на самом деле используете). Я предполагаю, что вы работаете с 32-разрядными числами без знака и хотите получить 64-разрядные результаты без знака.
Логический сдвиг влево на 1 бит:
tmp = lo >> 31; /* top bit of lo to bottom bit of tmp, rest of tmp is 0 */
lo <<= 1;
hi <<= 1;
hi |= tmp;
Логический сдвиг вправо на 1 бит:
tmp = hi << 31; /* bottom bit of hi to top bit of tmp, rest of tmp is 0 */
hi >>= 1;
lo >>= 1;
lo |= tmp;
(фактически вы можете заменить 1
и 31
на n
и (32 - n)
для сдвига на некоторое другое количество бит)
64-разрядное дополнение:
result_lo = a_lo + b_lo;
result_hi = a_hi + b_hi;
if (result_lo < a_lo)
result_hi++;
(см. здесь для более подробной информации об этом, со специальной ссылкой на MIPS).
Альтернативный подход - рассматривать каждый из ваших 32-битных входов как пару 16-битных «цифр»; умножение двух 16-битных чисел дает максимум 32-битный результат. Итак, основная идея такова:
0x12345678 * 0x23456789 = 0x5678 * 0x6789
+ ((0x1234 * 0x6789) << 16)
+ ((0x5678 * 0x2345) << 16)
+ ((0x1234 * 0x2345) << 32)
(вам все равно понадобятся некоторые 64-битные дополнения).