Я пишу небольшую библиотеку bignum для домашнего проекта. Я должен реализовать умножение Карацубы, но перед этим я хотел бы написать простую процедуру умножения.
Я следую руководству Пола Циммермана под названием «Современная компьютерная арифметика», которое свободно доступно в сети .
На странице 4 приведено описание алгоритма под названием BasecaseMultiply, который выполняет умножение в начальной школе.
Я понимаю шаг 2, 3, где B ^ j - сдвиг цифр 1, j раз.
Но я не понимаю шаг 1 и 3, где у нас есть A * b_j. Как это умножение должно быть выполнено, если умножение Бигнума еще не было определено?
Будет ли операция "*" в этом алгоритме просто методом повторного сложения?
Вот части, которые я написал до сих пор. Я проверил их юнит-тесты, поэтому они выглядят правильными по большей части:
Структура, которую я использую для моего bignum, выглядит следующим образом:
#define BIGNUM_DIGITS 2048
typedef uint32_t u_hw; // halfword
typedef uint64_t u_w; // word
typedef struct {
unsigned int sign; // 0 or 1
unsigned int n_digits;
u_hw digits[BIGNUM_DIGITS];
} bn;
В настоящее время доступны процедуры:
bn *bn_add(bn *a, bn *b); // returns a+b as a newly allocated bn
void bn_lshift(bn *b, int d); // shifts d digits to the left, retains sign
int bn_cmp(bn *a, bn *b); // returns 1 if a>b, 0 if a=b, -1 if a<b