Курсовая работа: Реализация класса больших чисел

Курсовая работа: Реализация класса больших чисел




🛑 👉🏻👉🏻👉🏻 ИНФОРМАЦИЯ ДОСТУПНА ЗДЕСЬ ЖМИТЕ 👈🏻👈🏻👈🏻




























































Реализовать средствами языка С++ класс больших целых чисел. Для написания класса были выделены следующие задачи:
· Организовать чтение из консоли и печать в консоль целых чисел, длина которых превышает 2 32
разрядов (стандартный тип long)
· Реализовать выполнение арифметических операции с данными числами:
o Нахождение целой части от деления
Первым делом была выбрана структура класса больших целых чисел. Так как число может быть как положительным, так и отрицательным было введено символьное поле, отвечающее за знак числа «+» или «–». Само число решено было записывать с помощью очереди с двусторонним доступом (deque) – контейнер из стандартной библиотеки шаблонов (STL). Очередь представляет собой динамический массив с множеством стандартных методов для его обработки. «Цифру» каждого разряда большого числа мы будем помещать в соответствующую ячейку массива. Например, число 12345, записанное с помощью deque mas; будет выгледеть как набор элементов этого массива: mas[0] = 1, mas[1] = 2, mas[2] = 3, mas[3] = 4, mas[4] = 5. Также класс будет содержать некоторое количество методов, для решения поставленных задач. Класс будет иметь название BigInteger. Структура класса изображена на рисунке 1.
Далее перешли к разработке методов класса. Сначала для непосредственной работы с большими числами были реализованы методы для чтения числа из консоли и печати в консоль – chtenie() и vector_print(BigInteger) соответственно.
Метод chtenie() считывает в виде строки данные введенные в консоль. Затем проверяет первый символ строки на наличие знака «–». Потом посимвольно, используя вспомогательную строку, содержащую цифры («0123456789»), заносит каждую цифру в конец очереди-массива. На выходе мы получаем большое число, содержащее знак «», либо «–». Также в методе используется вспомогательный метод dell_null(BigInteger), который возвращает число, удаляя впереди стоящие ничего не значащие нули (т.е. 00123 –> 123).
Метод vector_print(BigInteger) выполняет печать в консоль числа, предварительно задействовав, описанный выше вспомогательный метод dell_null(BigInteger). Сначала происходит печать знака числа, затем, используя цикл, выполняется печать каждого элемента очереди-массива. Результаты работы методов представлены на рисунке 2.
Рис. 2. Ввод-вывод большого положительного и отрицательного числа в консоль
Затем был реализован метод сложения двух больших чисел summa (BigIneger, BigInteger). Сначала метод проверяет знаки переданных ему чисел, если знаки разные, он, немного модифицируя знаки, передает числа методу, вычисляющему разность двух больших чисел, речь о котором пойдет дальше. Если же знаки чисел одинаковые, непосредственно происходит операция их сложения. Принцип основан на сложении «столбиком». Находим «длину» минимального по разрядам числа, затем складываем поразрядно числа в пределах этой «длины», добавляя 1, если сумма на предыдущем шаге была > 9, находим остаток от деления полученного числа на 10 (int% 10) и записываем его в разряд, над которым выполнялась операция. После того, как разряды у одного из чисел закончатся, «добиваем» результирующее число цифрами из оставшихся разрядов большего числа. Естественно, чтобы произвести операцию с первым разрядом, нужно обратиться к последнему элементу нашей очереди массива. Пример сложения представлен на рисунке 3.
Следующей операцией над большими числами стала операция вычитания, представленная методом rasnost (BigInteger, BigInteger). Вначале метод проверяет знаки переданных ему чисел, если знаки чисел равные (с учетом знака разности), то метод передает числа методу summa (BigInteger, BigInteger). Например, 12 – (-7). Метод передаст 12 и 7 для обработки методу summa (BigInteger, BigInteger). Если знаки чисел разные, то происходит операция вычитания. Принцип основан на вычитании «столбиком». Находим число с меньшим количеством разрядов (меньшей «длиной»), ставим его вторым. И начинаем поразрядно вычитать. При этом, если в разряде первого числа значение больше, чем в разряде второго числа, прибавляем к разности этих чисел 10. Но на следующем шаге вычитаем 1 из следующего полученного результата поразрядного вычитания. Выполняем эти действия, пока не закончатся разряды наименьшего числа, затем «добиваем» результирующее число цифрами из оставшихся нетронутыми разрядов большего числа. Пример вычитания представлен на рисунке 4.
После того, как были реализованы операции сложения и вычитания, перешли к написанию операции умножения, которую выполняет метод proisvedenie (BigInteger, BigInteger). Также в его основе лежит принцип умножения «столбиком». Выбираем одно из больших чисел, и поэтапно умножаем числа из каждого разряда этого большого числа, на другое большое число. В результате на каждом шаге у нас получаются «промежуточные» большие числа, суммируя которые с помощью описанного выше метода summa (BigInteger, BigInteger) мы получаем необходимый нам результат. При этом не забываем в зависимости от разряда множителя «добивать» начальные разряды «промежуточных» больших чисел нулями. Как и в предыдущих операциях при поразрядном перемножении в результат мы записываем остаток от деления на 10 и, если результат поразрядного перемножения больше либо равен 10, то на следующем шаге перемножения мы прибавляем число равное целой части от деления предыдущего результата на 10. Также для ускорения процесса перемножения были выделены особые случаи – умножение на 0 и на 1. Пример перемножения двух больших чисел представлен на рисунке 5.
После реализации метода перемножения двух больших чисел операции возведения числа в степень и операция взятия факториала числа не представляют большой трудности, так как могут быть выражены через умножение. Метод stepen (BigInteget, int), представляющий операцию возведения в степень большого числа, принимает в качестве аргументов само большое число и целое число, задающее степень, в которую необходимо возвести большое число. Метод вызывает операцию перемножения числа на само себя в цикле, количество шагов которого равно заданной степени. После выполнения данного цикла получаем нужную нам степень большого числа. Метод factorial(BigInteger), представляющий операцию получения факториала большого числа, мог быть выполнен двумя способами: используя рекурсию или используя итерацию, т.е. цикл. Был выбран второй вариант, так как он более производительный и не требует повторного вызова метода factorial(BigInteger), что замедляло бы работу программы. Для перемножения здесь использовалось вспомогательное большое число, которое изначально приравнивалось к числу, факториал которого нужно было найти. Затем на каждом шаге итерации оно уменьшалось на 1. На каждом шаге это число умножалось на ранее полученный результат, т.е. получалась выражение вида N!=((N*N-1)*N-2*)…*1. После выполнения данного цикла получаем факториал заданного числа.
Рисунок 6. Вычисление факториала 1000
Построение проекта осуществлялось в режиме Release. Технические характеристики компьютера, на котором выполнялись расчеты, представлены на рисунке 7.
Рисунок 7. Технические характеристики
Для того, чтобы исключить возможное влияние операционной системы на время выполнения вычисления, был проведен численный эксперимент, результаты которого представлены в таблице 1.
Таблица 1. Время вычисления факториала 1000
Таким образом, программа вычисляет факториал 1000 в среднем за 2,442 секунды.
Пожалуй, самой сложной для реализации, является операция деления и нахождение остатка от деления двух больших чисел. Методы соответствующие данным операциям были названы delenie (BigInteger, BigInteger) и ostasok_delenie (BigInteger, BigInteger) соответсвенно. В основе лежит принцип деления «столбиком». Пример работы алгоритма приведен на рисунке 8.
Рис. 8. Операция деления и нахождение остатка от деления
Ход алгоритма следующий: сравниваем делитель с делимым, прибавляя поразрядно по одной цифре к делителю в случае, если получившийся делитель меньше делимого, при этом в частное записываем 0. На рисунке 8 видно этот этап: 2<7985, в частное записываем 0, затем 21<7985, в частное записываем 0, и так далее пока не поменяется знак неравенства 21367>7985. После этого запускается цикл по нахождению следующей цифры частного. На каждом шаге делитель прибавляется на величину равную самому делителю, пока он не станет больше либо равен нашему промежуточному делимому, т.е. 21367. Шаг цикла, на котором выполнится данное условие, и будет искомой цифрой для частного. Затем вычитаем из промежуточного делимого полученное в ходе цикла число и получаем промежуточный остаток. Так как он точно меньше делителя (в связи с предыдущими условиями), добавляем к нему следующую не задействованную цифру делимого и переходим к первому шагу алгоритма. Алгоритм считается выполненным, если получается остаток, меньший делителя и не осталось ни одной незадействованной цифры делимого. В зависимости от задачи, метод возвращает либо частное, либо остаток от деления.
Для удобства пользователей был введен еще один метод vishislenie(), который предоставляет возможность выполнять вышеперечисленные арифметические операции с двумя или одним большим числом путем простого ввода необходимого для вычисления выражения. Пример работы данного метода приведен на рисунке 9.
факториал большой число перемножение
1. Лаптев В.В., Морозов А.В. «Объектно-ориентированное программирование. Задачи и упражнения». Издательство: «Питер» 2007 г.
2. Лафоре Р. «Объектно-ориентированное программирование в С++». Издательство: «Питер», 2004 г.
Листинг 1. Файл BigInteger.h класс BigInteger.
#include // очередь (избиблиотеки STL)
deque vect; // «содержит» число
// ___________________ Сравнение модулей больших чисел____________
int sravnenie (BigInteger big1, BigInteger big2)
if (big1.vect.size() > big2.vect.size()) return 1; // 1, еслипервоечисло > второго
if (big1.vect.size() < big2.vect.size()) return -1; // -1, еслипервоечисло < второго
if (big1.vect.size() == big2.vect.size())
for (int i = 0; i < (int) big1.vect.size(); i++)
if (big1.vect.at(i) > big2.vect.at(i)) return 1;
if (big1.vect.at(i) < big2.vect.at(i)) return -1;
// ___________________ Чтение числа из консоли ___________________
string temp = «0123456789»; // вспомогательнаястрока
if (str.at(0) == minus.at(0)) big.znak = '-'; // определение знака числа
for (int i = 0; i < (int) str.length(); i++) // циклсчитывающийцифрыизстроки
if (str.at(i) == temp.at(j)) big.vect.push_back(j);
// ___________________ Функция удаления нулей из начала числа ____
BigInteger dell_null (BigInteger big)
// ___________________ Печать числа в консоль ____________________
big = dell_null(big); // убираем нули из начала числа
if (big.vect.size() == 1 && big.vect.at(0) == 0) big.znak = ' '; // если число равно 0, то не ставим знак
if (big.znak == '-') // если число отрицательное, сначала печатаем знак –
for (int i = 0; i < (int) big.vect.size(); i++)
// ___________________ Суммабольшихчисел _______________________
BigInteger summa (BigInteger big1, BigInteger big2)
if (big1.znak!= big2.znak) // если разные знаки, то отправляем на метод разность
if (big1.znak == '-') // заменяем– x+y на y-x
deque summa = deque(); // сюда записывается результат
int temp = 0; // 1 для добавления к старшему разряду
int metka = 0; // для вычисления позиции, с которой остаются разряды только одного числа
if (big1.vect.size() >= big2.vect.size()) // ставим большее число на первое место
for (int i = big1.vect.size() – 1, j = big2.vect.size() – 1; j >=0; i–, j–) // начиная с первых разрядов складываем числа
summa.push_front((big1.vect.at(i) + big2.vect.at(j) + temp)%10);
if ((big1.vect.at(i) + big2.vect.at(j) + temp) >= 10) temp = 1; else temp = 0; // прибавляем 1 наследующемшаге, еслисуммабольше 10
for (int i = metka-1; i >= 0; i–) // начиная с позиции метки добиваем цифрами из большего числа, учитывая возможное прибавление 1
summa.push_front((big1.vect.at(i)+temp)%10);
if ((big1.vect.at(i) + temp) == 10) temp = 1; else temp = 0;
if (temp == 1) summa.push_front(1); // срабатывает в случае когда увеличивается разряд, например 99+1=100
for (int i = big2.vect.size() – 1, j = big1.vect.size() – 1; j >=0; i–, j–)
summa.push_front((big2.vect.at(i) + big1.vect.at(j) + temp)%10);
if ((big2.vect.at(i) + big1.vect.at(j) + temp) >= 10) temp = 1; else temp = 0;
summa.push_front((big2.vect.at(i)+temp)%10);
if ((big2.vect.at(i) + temp) == 10) temp = 1; else temp = 0;
if (temp == 1) summa.push_front(1);
// ________________________ Разностьбольшихчисел ________________
BigInteger rasnost (BigInteger big1, BigInteger big2)
if (big2.znak == '-') big2.znak = ' '; // x–y преобразуем в x+y и передаем в метод суммы
if (big1.znak == big2.znak) return summa (big1, big2); // – x-y преобразуемв– (x+y) передаемметодусуммы
deque rasn = deque(); // сюда записывается разность
int temp = 0; // 1 для вычитания из старшего разряда
int metka = 0; // для вычисления позиции, с которой остаются разряды только одного числа
big1 = dell_null(big1); // предварительно удаляем незначащие нули из начала числа
if (sravnenie (big1, big2)!= -1) // ставим большее число сверху в столбике
for (int i = big1.vect.size() – 1, j = big2.vect.size() – 1; j >=0; i–, j–)
if ((big1.vect.at(i) – big2.vect.at(j) + temp) >= 0) // поразрядновычитаем
rasn.push_front (big1.vect.at(i) – big2.vect.at(j) + temp);
rasn.push_front (big1.vect.at(i) – big2.vect.at(j) + 10 + temp); // заимствуем 1 изстаршегоразряда
for (int i = metka-1; i >= 0; i–) // добиваем числами оставшихся разрядов, учитывая -1
rasn.push_front (abs((big1.vect.at(i)+temp+10)%10));
if ((temp == -1) && (big1.vect.at(i) + temp) < 0) temp = -1; else temp = 0;
for (int i = big2.vect.size() – 1, j = big1.vect.size() – 1; j >=0; i–, j–)
if ((big2.vect.at(i) – big1.vect.at(j) + temp) >= 0)
rasn.push_front (big2.vect.at(i) – big1.vect.at(j) + temp);
rasn.push_front (big2.vect.at(i) – big1.vect.at(j) + 10 + temp);
rasn.push_front (abs((big2.vect.at(i)+temp+10)%10));
if ((temp == -1) && (big2.vect.at(i) + temp) < 0) temp = -1; else temp = 0;
// _______________________ Произведениебольшихчисел _____________
BigInteger proisvedenie (BigInteger big1, BigInteger big2)
for (int i = big1.vect.size() – 1, count = 0; i >= 0; i –, count++)
if (big1.vect.at(i) == 0) {} // умножениена 0
if (big1.vect.at(i) == 1) // умножение на 1, просто прибавляем число с «добитыми» нулями
for (int k = 0; k < count; k++) // добиваем нулями в зависимости от разряда умножения
for (int k = 0; k < count; k++) // добиваемнулями
for (int j = big2.vect.size() – 1; j >=0; j–) // умножаемпервоечислона«цифру» изразрядаучитывая temp
reserv.vect.push_front((big1.vect.at(i)*big2.vect.at(j) + temp)%10);
if ((big1.vect.at(i)*big2.vect.at(j) + temp) >=10) temp = (big1.vect.at(i)*big2.vect.at(j) + temp)/10; else temp = 0;
if (temp!=0) reserv.vect.push_front(temp); // приувеличенииразрядовчисла
proisv = summa (reserv, proisv); // складываем предыдущие результаты
// __________________ Возведение в степень большого числа _________
BigInteger stepen (BigInteger big, int steps)
step.vect = big.vect; // постоянный множитель
for (int i = 1; i < steps; i++) // числошаговравноестепени
// __________________ Факториал большого числа ____________________
BigInteger faktorial (BigInteger big)
edinica.vect.push_back(1); // дляуменьшенияна 1
while (big.vect.size()!= 0 && big.vect.at(0)!= 0) // пока число не стало равным 0
// __________________ Деление больших чисел _______________________
BigInteger delenie (BigInteger delimoe, BigInteger delitel)
for (int i = 0; i < (int) delimoe.vect.size(); i++)
ostatok.vect.push_back (delimoe.vect.at(i)); // промежуточныйостаток
if (sravnenie (ostatok, delitel) == -1) {chastnoe.vect.push_back(0);} // покапромежуточныйостатокбольшеделителяпишемвчастное 0
for (int j = 0; j < 10; j++) // цикл, формирующий цифры частного
if (sravnenie (ostatok, reserv2) == -1) // промежуточный остаток меньше делителя*j
ostatok = rasnost (ostatok, reserv3);
if (sravnenie (ostatok, reserv2) == 0) // промежуточныйостатоккратныйделителю
reserv2 = summa (reserv2, delitel); // прибавляем сам делитель, пока не станет больше остатка
} // цифры делимого заканчиваются и остаток меньше делимого, цикл завершается
if (delimoe.znak!= delitel.znak) chastnoe.znak = '-';
// __________________ Остаток от деления больших чисел ____________
BigInteger ostatok_delenie (BigInteger delimoe, BigInteger delitel)
{ // все как в методе delenie(), только возвращаем не частное, а остаток
for (int i = 0; i < (int) delimoe.vect.size(); i++)
ostatok.vect.push_back (delimoe.vect.at(i));
if (sravnenie (ostatok, delitel) == -1) {chastnoe.vect.push_back(0);}
if (sravnenie (ostatok, reserv2) == -1)
ostatok = rasnost (ostatok, reserv3);
if (sravnenie (ostatok, reserv2) == 0)
reserv2 = summa (reserv2, delitel);
if (ostatok.vect.size() == 0) ostatok.vect.push_back(0);
// _________ Метод для использования выражений для вычисления _____
cin >> str; // считываем строку и в зависимости от знака выбираем действие с числами через switch
if (str.at(0) == snaki.at(0)) big1.znak = '-';
for (int i = 0; i < (int) str.length(); i++)
if ((perekluchatel == -1) && (str.at(i) == temp.at(j))) {big1.vect.push_back(j); break;}
if ((perekluchatel!= -1) && (str.at(i) == temp.at(j))) {big2.vect.push_back(j); break;}
if ((str.at(i) == snaki.at(j)) && (i!= 0))
if (str.at (i+1) == snaki.at(0)) big2.znak = '-'; break;
return rasnost (big1, big2); break;
return proisvedenie (big1, big2); break;
return delenie (big1, big2); break;
return ostatok_delenie (big1, big2); break;
while (big2.vect.size()!= 0 && big2.vect.at(0)!= 1)
BigInteger proverka = ostatok_delenie (tempbig2, dvoika);
#include «BigInteger.h» // подключаемклассбольшихцелыхчисел
void main() // функция использующая большие целые числа
int x, y; // переключатели режима вычисления
cout << «Выберите режим вычисления:\n1 – режим выражения\n2 – режим выбора операции\n ->»;
cout << «Введите выражение для вычисления:\n»;
cout << «\n\nВведите номер операции: \n»;
cout << «5 – остаток от деления чисел \n»;
cout << «6 – возведение в степень \n»;
cout << «8 – ввести новые числа\n»;
cout << «9 – выйти из программы\n»;
rasn = rasn.rasnost (bint1, bint2);
proisv = proisv.proisvedenie (bint1, bint2);
chastnoe = chastnoe.delenie (bint1, bint2);
cout << «\nОстаток от деления чисел:»;
chastnoe = chastnoe.ostatok_delenie (bint1, bint2);
cout << «Введите в какую степень нужно возвести первое число:»;
cout << «\n» << st <<» – аястепеньчисла:»;
cout << «\nФакториал первого числа:»;
cout << «\nОшибка ввода, повторите процедуру!»;

Название: Реализация класса больших чисел
Раздел: Рефераты по информатике, программированию
Тип: курсовая работа
Добавлен 10:49:00 13 апреля 2011 Похожие работы
Просмотров: 3466
Комментариев: 16
Оценило: 8 человек
Средний балл: 3.9
Оценка: 4   Скачать

Срочная помощь учащимся в написании различных работ. Бесплатные корректировки! Круглосуточная поддержка! Узнай стоимость твоей работы на сайте 64362.ru
Под данному алгоритму при делении, например, числа 48354 на 2320 в ответе получится 2 с остатком :)
Привет студентам) если возникают трудности с любой работой (от реферата и контрольных до диплома), можете обратиться на FAST-REFERAT.RU , я там обычно заказываю, все качественно и в срок) в любом случае попробуйте, за спрос денег не берут)
Да, но только в случае крайней необходимости.

Курсовая работа: Реализация класса больших чисел
Реферат по теме Острый лейкоз (Leucosis acuta)
Курсовая Работа На Тему Бронхиальная Астма У Взрослых
Реферат: Marketing Products In India Essay Research Paper
Реферат: Opposition To The New Deal Essay Research
Егэ Русский Язык 2022 Год Сочинение
Автореферат На Тему Электрохимические Процессы На Границе. Твердый Электролит. Соединения Внедрения
Курсовая работа по теме Програма обчислення другої похідної за інтерполяційною формулою Стірлінга
Челгу Титульный Лист Курсовой Работы
Написать Сочинение Церковь Покрова На Нерли
Реферат: Расчёт технико-экономических показателей участка по изготовлению детали крышка МТП- 44А
Пример Титульного Листа Реферата Для Школы
Контрольная работа по теме Девиантное поведение несовершеннолетних
Реферат по теме Портретисты первой половины XIX в.
Стоимость Собрания Сочинений Ленина
Реферат по теме Эмоции и психические состояния
Курсовая работа по теме Расчет электроэнергетической системы
Курсовая Работа Приказное Производство
Дипломная работа: Социально-педагогическая работа с безработными гражданами
Мен Мәңгілік Елдің Ұрпағымын Эссе
Реферат по теме Екологічні та абіотичні фактори
Статья: Эффекты межличностного восприятия
Доклад: Компьютерные определители
Реферат: История страхования

Report Page