Работая над своей собственной целочисленной реализацией, я просмотрел исходный код Java BigInteger для более глубокого понимания алгоритмов умножения и сосредоточился в основном на multiplyToLen()
.
В целом, функция, кажется,Возьмите общий алгоритм умножения в начальной школе, но я не могу понять его ключевые части.
Сначала алгоритм проходит этот первый цикл, где x и y - умножаемые два числа, а z - произведение:
int xstart = xlen - 1;
int ystart = ylen - 1;
...
for (int j=ystart, k=ystart+1+xstart; j >= 0; j--, k--) {
long product = (y[j] & LONG_MASK) * (x[xstart] & LONG_MASK) + carry;
z[k] = (int)product;
carry = product >>> 32;
}
z[xstart] = (int)carry;
Затем он переходит к следующему циклу.Это кажется намного ближе к алгоритму школьной школы.
for (int i = xstart-1; i >= 0; i--) {
carry = 0;
for (int j=ystart, k=ystart+1+i; j >= 0; j--, k--) {
long product = (y[j] & LONG_MASK) * (x[i] & LONG_MASK) +
(z[k] & LONG_MASK) + carry;
z[k] = (int)product;
carry = product >>> 32;
}
z[i] = (int)carry;
}
Я попытался отследить оба цикла с использованием десятичных чисел безрезультатно, и я не могу понять функцию первого цикла по сравнению со вторым циклом.
Какая часть алгоритма умножения выполняется в первом цикле?