Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
raport.doc
Скачиваний:
4
Добавлен:
09.02.2015
Размер:
106.5 Кб
Скачать

LongNumber

LongNumber::operator* (const LongNumber& number)

{

LongNumber result;

// Ссылки на большее и меньшее по модулю исходные числа.

// Обычно при умножении в столбик, сверху записывают

// большее число. Поступим также.

const LongNumber *big, *small;

// Сравниваем модули чисел и присваиваем ссылки на них

// соответствующим указателям.

if (compareModules(*this, number) < 0) {

big = this;

small = &number;

}

else {

small = this;

big = &number;

}

// Присваиваем результирующему числу знак.

result.sign_ = this->sign_ * number.sign_;

// Результирующее число не может иметь большую

// разрядность чем удвоеная разрядность большего из исходных

// чисел. Впоследствии лишние старшие разряды результата

// будут обрезаны.

result.setLength(big->length_ * 2);

// Временные переменные.

int over, res, final, finOver, i, j;

over = res = 0;

// Во внешнем цикле перебираем поочередно разряды меньшего из чисел,

// как мы делали это в школе.

for (i = 0; i < small->length_; i++)

{

// Во внутреннем цикле перемножаем поочередно разряды большего

// числа на текущий разряд меньшего.

for (j = 0; j < big->length_; j++)

{

// Вычисляем произведение текущих разрядов и прибавляем к нему

// значение [i+j] разряда результирующего числа.

res = small->array_[i] * big->array_[j] + result.array_[i + j];

// Если результат предыдущей операции (res) оказался больше

// основания, значит в [i+j] разряде результирующего числа следует

// оставить остаток от деления res на основание (res % BASE),

// а остальное перенести в следующий по старшинству разряд.

if (res >= BASE)

{

result.setDigit(i + j, res % BASE);

// То, что будет перенесено в следующий разряд.

over = res / BASE;

// Вычисляем сумму следующего по старшинству разряда результата и over.

final = result.array_[i + j + 1] + over;

// Если эта сумма (final) также получилась больше основания,

// то начинаем переносить лишнее в следующие по старшинству разряды,

// до тех пор, пока final не станет меньше основания.

if (final >= BASE)

{

finOver = final / BASE;

int k = 1;

while (finOver > 0) {

result.setDigit(i + j + k, final % BASE);

k++;

final = result.getDigit(i + j + k) + finOver;

result.setDigit(i + j + k, final % BASE);

finOver = final / BASE;

}

}

// Иначе, записываем final в следующий по старшинству разряд

// и обнуляем over.

else

{

result.setDigit(i + j + 1, final);

over = 0;

}

}

// Иначе записываем res в [i+j] разряд.

else

{

result.setDigit(i + j, res);

}

}

}

// Отрежем ведущие нули, если они есть.

int zeros = 0;

for (int dig = 0, i = result.length_ - 1; dig == 0; i--) {

dig = result.array_[i];

if (dig == 0) zeros++;

}

LongNumber r;

r.setLength(result.length_ - zeros);

for (int i = 0; i < result.length_ - zeros; i++)

r.setDigit(i, result.array_[i]);

// Установим знак результирующего числа

r.sign_ = this->sign_ * number.sign_;

return r;

}

Деление: реализация операции деления "в столбик" примечальна тем, что требует на каждом шаге нахождения такого максимального x, который удовлетворял бы неравенству: x * a ≤ b, где a - делитель, а b - число, состоящее из старших разрядов делимого, и большее либо равное делителя. Причем x ∊ [1..9999]. В нашем случае нахождение такого числа реализовано методом бинарного поиска. Также, в случае деления на ноль, выводится соответствующее сообщение и возвращается нулевое длинное число.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]