LongNumber
LongNumber::sum (const LongNumber& a, const LongNumber& b)
{
LongNumber result;
// Флаг переноса
bool overFlag = false;
// Указатель на большее из чисел по длине массива. В случае переноса
// значение следующего по старшенству разряда будет увеличиваться
// на единицу в этом числе.
int compareNumbers = compareModules(a, b);
const LongNumber* biggerNumber = (compareNumbers < 0) ? &a : &b;
// Длина результирующего массива окажется равной или большей на
// единицу длины большего из начальных массивов.
result.setLength(maximum(a.length_, b.length_));
// Теперь берем меньшую из двух длин массивов.
int minLength = minimum(a.length_, b.length_);
// И складываем разряды чисел начиная с младших
for (int i = 0; i < minLength; i++)
{
// Считаем пока просто сумму разрядов.
// Если на предыдущем шаге был установлен флаг переполнения
// overFlag, добавляем к сумме единицу.
int digitSum = a.array_[i] + b.array_[i] + ((overFlag) ? 1 : 0);
// Теперь смотрим, если сумма помещается в разрядную сетку
// записываем ее как есть, иначе записываем в разряд
// sum - BASE и устанавливаем флаг переноса в true
// Это означает, что при сложении следующих по старшинству
// разрядов исходных чисел, к сумме будет добавлена единица.
if (digitSum < BASE) {
overFlag = false;
result.setDigit(i, digitSum);
}
else {
overFlag = true;
result.setDigit(i, digitSum - BASE);
}
}
// Если длина большего числа на самом деле была больше, чем у меньшего
// (они ведь могли быть и равны), дописываем в результирующее число
// старшие разряды большего числа. Только не забываем про флаг
// переполнения, который мог остаться в положении true с предыдущего
// этапа суммирования.
if (biggerNumber->length_ > minLength) {
// Берем теперь уже длину большего числа, она же равна длине
// результирующего.
int biggerLength = biggerNumber->length_;
for (int i = minLength; i < biggerLength; i++) {
// Будем записывать результирующие разряды через временную
// переменную, т.к. это даст возможность добавлять к
// разряду единицу в случае переполнения младших разрядов.
int digit = biggerNumber->array_[i] + ((overFlag) ? 1 : 0);
if (digit < BASE) {
overFlag = false;
result.setDigit(i, digit);
}
else {
overFlag = true;
result.setDigit(i, digit - BASE);
}
}
}
// И под конец проверяем, требуется ли дополнительный старший разряд
// Т.е. если даже на последнем шаге флаг переполнения остался true,
// значит в результирующем числе должно быть на один больше разрядов,
// чем в большем из исходных чисел. И в этом разряде будет единица.
if (overFlag) {
LongNumber resultWithAddDigit;
resultWithAddDigit.setLength(result.length_ + 1);
for (int i = 0; i < resultWithAddDigit.length_; i++)
resultWithAddDigit.setDigit(i, result.getDigit(i));
resultWithAddDigit.setDigit(resultWithAddDigit.length_ - 1, 1);
return resultWithAddDigit;
}
else {
return result;
}
}
// Функция устанавливает значение разряда числа
void
LongNumber::setDigit(int digit, int value)
{
if (digit >= 0 && digit < length_)
array_[digit] = value;
}
// Функция возвращает значение разряда числа
int
LongNumber::getDigit(int digit)
{
if (digit >= length_ || digit < 0) return -1;
else return array_[digit];
}
Умножение: данную операцию следует описать до описания операции деления, т.к. последняя в своей реализации использует первую.