Полагаю, вы имеете в виду, что вы можете умножать только два 16-разрядных числа за раз.
Сначала я скажу, что a
и b
- это числа, которые мы хотим умножить. Они имеют размер от 17 до 32 бит (что покрывает ваши 23). Какими бы большими они ни были, они дополняются нулями до 32-разрядного размера без знака.
r = a * b
можно переписать как
r = (al + (ah << 16)) * (bl + (bh << 16))
, где al
и ah
- младшая и старшая 16-битные части a
. Сдвиг на 16 - это то же самое, что умножение на 2 ^ 16. Затем мы можем расширить это уравнение.
r = (al + (ah * 2^16)) * (bl + (bh * 2^16))
r = al * bl + al * (bh * 2^16) + (ah * 2^16) * bl + (ah * 2^16) * (bh * 2^16)
r = al * bl + al * bh * 2^16 + ah * bl * 2^16 + ah * bh * 2^32
r = al * bl + (al * bh + ah * bl) << 16 + (ah * bh) << 2^32
Таким образом, вы получите 4 умножения (al*bl
, al*bh
, ah*bl
& ah*bh
), и вы сдвинете результаты и сложите их вместе. Имейте в виду, что каждое 16-разрядное умножение дает 32-разрядный результат, так что все это перейдет в 64-разрядное. В вашем случае, поскольку вы знаете, что a
& b
не больше 2 ^ 23, все это уместится в 46 бит.
Другое дело, что суммирование должно быть выполнено в 16-битных блоках с заботливыми битами переноса.
Надеюсь, это поможет.