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

LongNumber

LongNumber::operator/ (const LongNumber& number)

{

LongNumber result;

// Проверка на нулевой делитель и на то, что делитель больше делимого (по модулю)

if (compareModules(*this, number) > 0)

return result;

if (number.length_ == 1 && number.array_[0] == 0) {

std::cerr << "Divizion by zero.\n";

return result;

}

// Создаем переменные, с которыми будем работать

LongNumber dividend (*this);

LongNumber divisor (number);

// Сделаем обе переменные положительными

dividend.sign_ = divisor.sign_ = 1;

// Временное хранилище для результатов деления

int storage[dividend.length_];

for (int i = 0; i < dividend.length_; i++)

storage[i] = -1;

int storagePosition = 0;

int storageLen = dividend.length_;

// Остаток от разности (elderDigits - x * divisor) (см. ниже)

LongNumber remainder;

// Узнаем длину делителя

int divisorLen = divisor.length_;

while (dividend >= divisor)

{

// Создаем переменную для старших разрядов делимого количеством divisorLen

LongNumber elderDigits;

elderDigits.setLength(divisorLen);

for (int i = dividend.length_ - divisorLen, j = 0; i < dividend.length_; i++, j++)

elderDigits.array_[j] = dividend.array_[i];

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

// нужно взять на один разряд больше из делимого.

if (elderDigits < divisor) {

elderDigits.setLength(divisorLen + 1);

for (int i = dividend.length_ - divisorLen - 1, j = 0; i < dividend.length_; i++, j++)

elderDigits.array_[j] = dividend.array_[i];

}

// Найдем такое максимальное x, которое удовлетворяло бы условию

// x * divisor <= elderDigits. x будет лежать в пределах (0..BASE)

int x = 0, w = 0, left = 0, right = BASE;

LongNumber supposition;

while (left <= right)

{

w = (left + right) >> 1;

supposition = divisor * w;

if (supposition > elderDigits)

{

right = w - 1;

}

else

{

left = w + 1;

x = w;

}

}

// Поместим полученный x во временное хранилище

storage[storagePosition++] = x;

// Запомним длину elderDigits

int elderDigitsLen = elderDigits.length_;

// Вычисляем остаток от разности (elderDigits - x * divisor)

remainder = elderDigits - (divisor * x);

// Если remainder оказался равен нулю, то помещаем в него поочередно следующие разряды dividend

// до тех пор пока не найдем ненулевой разряд или не закончится делимое.

// Если очередной разряд нулевой, сохраняем 0 в storage и увеличиваем elderDigitsLen на единицу.

LongNumber zeroNumber;

while (remainder == zeroNumber && elderDigitsLen < dividend.length_)

{

elderDigitsLen++;

remainder.setLength(1);

remainder.array_[0] = dividend.array_[dividend.length_ - elderDigitsLen];

if (remainder == zeroNumber) {

storage[storagePosition++] = 0;

}

}

// Вычислим насколько нужно сдвинуть remainder влево

int sh = dividend.length_ - elderDigitsLen;

// Сдвигаем

remainder = remainder << sh;

// Копируем оставшиеся младшие разряды dividend в младшие разряды remainder i = 0..sh-1

for (int i = 0; i < sh; i++)

remainder.array_[i] = dividend.array_[i];

// Заменяем dividend на remainder.

dividend = remainder;

}

// Теперь скопируем результаты из временного хранилища в результирующее число.

// Сначало посмотрим, какой длины должно быть число

int resultLen = 0;

for (int i = storageLen - 1; i >= 0; i--)

if (storage[i] >= 0)

resultLen++;

// Зададим длину результирующего числа

result.setLength(resultLen);

// Скопируем полученные резьтаты в разряды числа

for (int i = storageLen - 1, j = 0; i >= 0; i--)

{

if (storage[i] >= 0)

{

result.array_[j] = storage[i];

j++;

}

}

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

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

return result;

}

// Оператор поразрядного сдвига влево

// Равносильно умножению числа на BASE^n

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