[P&AM Lab] Постановка задачи по KML
Grigoriy A. Sitkarev
sitkarev на komitex.ru
Вт Мар 8 09:47:41 MSK 2011
Ещё кое-что упустил из виду. Уж простите.
Закомментировал ненужные строки в этой функции, мы же уже посчитали z0 и
z2 на предыдущем шаге.
Добавлю ещё следующее. В функции kmul_basic() вычисление z1 уже не
вмещается в машинную арифметику 32-х разрядной машины, т.к. x0..y1 числа
по 32 бита, их сумма и произведение будет больше чем 64 бита. Поэтому
там эти операции уже как с bignum должны быть сделаны. Числа z2 и z0
вмещаются в u_int64_t, поэтому вероятно стоит какую-то функцию потом
написать чтобы из bignum вычитать/прибавлять u_int64_t без необходимости
представления z0 и z1 в bignum (видимо что-то вроде bignum_add_int() и
bignum_sub_int() и т.д.).
Экономия достигается за счёт того что после того как мы посчитали z0 и
z1 во внешней функции рекурсивной длинное умножение, чтобы получить z1,
выполняется для чисел почти в два раза меньше порядком чем исходное. А
т.к. у нас длинное умножение O(n^2) -- эффект будет ощущаться на очень
больших числах.
Надо искать дальше где у нас неточности. Всё равно это только наброски.
8<--------------------------------------------------------------------
function
kmul_recursive(xy [out], x1 [in], y1 [in], x0 [in], y0 [in], n [in])
{
temp z0, z1, z2;
m = n / 2;
if (m <= basic_size) {
kmul_basic(z2, x1+m, y1+m, x1, y1, m);
kmul_basic(z0, x0+m, y0+m, x0, y0, m);
} else {
kmul_recursive(z2, x1+m, y1+m, x1, y1, m);
kmul_recursive(z0, x0+m, y0+m, x0, y0, m);
}
/* z2 = x1 * y1; */
/* z0 = x0 * y0; */
z1 = (x1 + x0)*(y1 + y0) - z2 - z0;
shift_left(z2, 2*m);
shift_left(z1, m);
xy = add3(z0, z1, z2);
}
8<-------------------------------------------------------------------
--
Г.А.
07.03.2011 12:16, Grigoriy A. Sitkarev пишет:
> Заметили опечатки.
>
> Исправленный псевдо-код и портянка со схемой.
>
Подробная информация о списке рассылки Lab