Курсовая: Манипулирование с целыми числами произвольной длины - текст курсовой. Скачать бесплатно.
Банк рефератов, курсовых и дипломных работ. Много и бесплатно. # | Правила оформления работ | Добавить в избранное
 
 
   
Меню Меню Меню Меню Меню
   
Napishem.com Napishem.com Napishem.com

Курсовая

Манипулирование с целыми числами произвольной длины

Банк рефератов / Математика

Рубрики  Рубрики реферат банка

закрыть
Категория: Курсовая работа
Язык курсовой: Русский
Дата добавления:   
 
Скачать
Microsoft Word, 151 kb, скачать бесплатно
Обойти Антиплагиат
Повысьте уникальность файла до 80-100% здесь.
Промокод referatbank - cкидка 20%!

Узнайте стоимость написания уникальной работы

 

 

Манипулирование с целыми числами произвольной длины

Постановка задачи:

Составить набор процедур манипулирования с целыми числами произвольной длины. Процедуры должны обеспечивать: формирование и ввод целых чисел произвольной длины, сложение, вычитание, сравнение и умножение целых чисел. Работоспособность процедур продемонстрировать на демонстрационной программе.

Использованные средства языка:

Модуль, реализующий целые числа произвольной длины, и тестовая программа написаны на языке С++.

Для представления целых чисел произвольной длины определен класс UNLIM. Операции над этими числами реализованы путем переопределения для класса UNLIM следующих операций:

+ (унарный и бинарный)

- (унарный и бинарный)

*

==

!=

<

>

<=

>=

<< (операция вывода класса OSTREAM) .

Структура данных:

Абсолютная величина числа произвольной длины хранится в памяти в виде массива типа CHAR. В каждом элементе массива может находится число от 0 до 99, то есть два разряда всего числа. В нулевом элементе хранятся младшие два разряда, в последнем элементе - старшие два разряда. Если число имеет нечетное количество разрядов, то в последнем элементе массива хранится один последний разряд, т.е. число от 0 до 9. Лидирующие нули в массиве не хранятся. Число 0 представлено массивом из одного элемента, в котором хранится 0.

С целью минимизировать копирование и расход памяти класс UNLIM реализован так, что на одно представление абсолютной величины могут ссылаться несколько чисел, при этом ведется учет ссылок.

Объект класса UNLIM состоит из поля SIGN - знака числа и поля PV - указателя на дескриптор представления абсолютной величины. Число 0 всегда имеет знак PLUS.

Дескриптор представления абсолютной величины числа представляет собой объект структуры DESCRIPTOR и имеет следующие поля:

body - указатель на массив, в котором хранится представление абсолютной величины числа;

len - длина массива body[] в байтах;

HowMany - количество ссылок на данное представление;

Реализация операций сравнения:

Из операций сравнения только < и != напрямую сравнивают числа, остальные операции выражены через эти две. При работе операций < и != сначала проверяются знаки и длины чисел, и только в случае их совпадения производится поразрядное сравнение чисел (в качестве разрядов здесь берутся целые байты - т.е. разряды в системе счисления с основанием 100).

Реализация операций арифметики:

Операция унарный + просто возвращает само число.

Операция унарный - возвращает новый объект класса UNLIM, который ссылается на то же представление модуля числа, что и аргумент, и имеет знак, противоположный знаку аргумента.

Операция бинарный + определена и для случаев, когда знаки операндов совпадают, и когда эти знаки различны.

В первом случае знак результата соответствует знаку одного (любого) из операндов, а модуль результата является результатом сложения модулей операндов. При этом если количество разрядов первого операнда равно A, а второго - B, то количество разрядов операнда может быть либо max(A,B), либо max(A,B)+1, поэтому при выделении памяти под массив для модуля результата берется второе значение. Никакой оптимизации этого массива после сложения модулей операндов не делается, так как в данном случае потеря памяти на лидирующие нули может быть максимум 1 байт, и выгоднее сэкономить на скорости, чем на памяти.

В случае, когда знаки операндов различны, знак результата равен знаку операнда с максимальным модулем, а модуль результата получатся вычитанием модуля операнда с минимальным модулем из модуля операнда с максимальным модулем. При этом под модуль результата выделяется массив длины, равной наибольшей из длин операндов, но после вычитания чисел он оптимизируется функцией optimize(), которая удаляет лидирующие нули (создает новый массив длины, необходимой для хранения модуля числа без лидирующих нулей, копирует в него все значащие разряды, переадресовывает ссылку дескриптора на этот массив и удаляет старый массив).

Сложение и вычитание модулей аргументов производится в системе счисления с основанием 100.

Операция бинарный - определена через унарный минус и бинарный плюс.

Операция * производится по технологии, аналогичной умножению в столбик. При этом все действия ведутся в системе счисления с основанием 100. Длина массива результата может быть равна либо сумме длин операндов, либо этой сумме минус 1. Эта ситуация аналогична той, которая была при сложении чисел с одинаковым знаком, и здесь тоже не делается оптимизации.

Операция << - просто операция вывода класса OSTREAM, определенная для класса UNLIM. Сначала она выводит '-' если знак числа отрицательный, а затем само число поразрядно (по десятичным разрядам), начиная со старшего. При этом используется функция digit(number), которая возвращает значение десятичного разряда с номером number.

Функция- конструктор unlim(char*) обрабатывает инициализацию символьной строкой. При этом распознаются следующие ошибочные ситуации: инициализация пустой строкой; недопустимый символ в строке; строка содержит знак, но не содержит значения. Во всех этих случаях число инициализируется нулем.

Функция- конструктор unlim(unlim&) обрабатывает инициализацию другим объектом класса UNLIM.

Отчет тестовой программы

Проверка работы конструкторов:

Без инициализации:

unlim a;

a=0

Инициализация строкой:

unlim b="123"

b=123

unlim c="-123"

c=-123

unlim d="+123"

d=123

unlim e="+" Unlim class error: Sign without value. Value=0

e=0

unlim f="-" Unlim class error: Sign without value. Value=0

f=0

unlim g="aaa" Unlim class error: Not digit symbol in string. String ignored. Value=0

g=0

unlim h="4a123" Unlim class error: Not digit symbol in string. String ignored. Value=0

h=0

Проверка вывода, арифметики и сравнения:

Введено:

a=123

b=45

Результат:

a=123

b=45

a=-123 +a=123

a>b a>=b a!=b

a+b=168 a-b=78 a*b=5535

Введено:

a=+0000000000000000123

b=0000000000000000000000000000000045

Результат:

a=123

b=45

a=-123 +a=123

a>b a>=b a!=b

a+b=168 a-b=78 a*b=5535

Введено:

a=-123

b=-45

Результат:

a=-123

b=-45

a=123 +a=-123

a

a+b=-168 a-b=-78 a*b=5535

Введено:

a=123

b=-45

Результат:

a=123

b=-45

a=-123 +a=123

a>b a>=b a!=b

a+b=78 a-b=168 a*b=-5535

Введено:

a=-123

b=45

Результат:

a=-123

b=45

a=123 +a=-123

a

a+b=-78 a-b=-168 a*b=-5535

Введено:

a=1000000000000000000000000000000000000000000000

b=999999999999999999999999999999999999999999999

Результат:

a=1000000000000000000000000000000000000000000000

b=999999999999999999999999999999999999999999999

a=-1000000000000000000000000000000000000000000000 +a=1000000000000000000000000000000000000000000000

a>b a>=b a!=b

a+b=1999999999999999999999999999999999999999999999 a-b=1 a*b=999999999999999999999999999999999999999999999000000000000000000000000000000000000000000000

Введено:

a=-100000000000000000000000000000000000000000000

b=999999999999999999999999999999999999999999999

Результат:

a=-100000000000000000000000000000000000000000000

b=999999999999999999999999999999999999999999999

a=100000000000000000000000000000000000000000000 +a=-100000000000000000000000000000000000000000000

a

a+b=899999999999999999999999999999999999999999999 a-b=-1099999999999999999999999999999999999999999999 a*b=-99999999999999999999999999999999999999999999900000000000000000000000000000000000000000000

Введено:

a=+00000000000000

b=-00000000000000

Результат:

a=0

b=0

a=0 +a=0

a<=b a>=b a==b

a+b=0 a-b=0 a*b=0

programm1;

//#include

#include

#include

//#include

#include "unlimit.h"

#define CR "\n"

void main()

{

ofstream r("report.txt",1);

ostream_withassign rc;

rc=cout;

cout<<"\nТестовая программа для класса UNLIM\n"

<<"(целые числа с произвольной точностью)\n"

;

cout=r;

r <<"Отчет тестовой программы\n"

<<"\nПроверка работы конструкторов:\n"

<<" Без инициализации:\n"

;

r <<" unlim a;\n";

unlim a;

r <<" a="<

<<" Инициализация строкой:\n"

<<" unlim b=\"123\"\n";

unlim b="123";

r <<" b="<

<<" unlim c=\"-123\"\n";

unlim c="-123";

r <<" c="<

<<" unlim d=\"+123\"\n";

unlim d="+123";

r <<" d="<

<<" unlim e=\"+\"\n";

unlim e="+";

r <<" e="<

<<" unlim f=\"-\"\n";

unlim f="-";

r <<" f="<

<<" unlim g=\"aaa\"\n";

unlim g="aaa";

r <<" g="<

<<" unlim h=\"4a123\"\n";

unlim h="4a123";

r <<" h="<

<<"Проверка вывода, арифметики и сравнения:\n\n";

while ( a!="0" || b!="0" )

{

cout=rc;

cout<<"\nВводите одно за другим 2 числа; для окончания - оба нули\n";

char

aa[128],

bb[128];

cout<<" a=";

cin >>aa;

cout<<" b=";

cin >>bb;

cout=r;

r <<"Введено:\n"

<<" a="<

<<" b="<

<<"\nРезультат:\n"

;

a=aa;

b=bb;

r <<" a="<

<<"-a="<<-a<

if (a

if (a>b) r<<"a>b ";

if (a<=b) r<<"a<=b ";

if (a>=b) r<<"a>=b ";

if (a!=b) r<<"a!=b\n";

if (a==b) r<<"a==b\n";

r <<"\na+b="<<(a+b)<

<<"a-b="<<(a-b)<

<<"a*b="<<(a*b)

<<"\n\n--------------------------------------------------\n\n"

;

}

}

programm2;

#define COUNT unsigned int

#define TRUE 1

#define FALSE 0

#define ILLEGAL 10

enum

{

PLUS,

MINUS

};

extern class unlim

{

public:

unlim(char*);

unlim();

unlim(unlim&);

~unlim();

unlim

&operator = (char*),

&operator = (unlim&);

friend int

operator == (unlim&,unlim&),

operator != (unlim&,unlim&),

operator > (unlim&,unlim&),

operator >= (unlim&,unlim&),

operator < (unlim&,unlim&),

operator <= (unlim&,unlim&);

friend unlim

operator + (unlim&), // unary

operator - (unlim&), // unary

operator + (unlim&,unlim&), // binary

operator - (unlim&,unlim&), // binary

operator * (unlim&,unlim&),

abs(unlim&);

friend ostream

&operator << (ostream&,unlim&);

private:

struct descriptor

{

char

*body;

COUNT

len,

HowMany;

};

descriptor

*pv; //pointer to value descriptor

char

sign,

digit(COUNT number);

char

&operator [](COUNT i) {return pv->body[i];}

void

init0(), //init by zero

NotDigit(), //message "no digit" & init0

optimize(), //optimize length of body

error(char*); //display error message

};

inline int operator ==(unlim &a,unlim &b)

{

return !(a!=b);

}

inline int operator <=(unlim &a,unlim &b)

{

return (a

}

inline int operator >=(unlim &a,unlim &b)

{

return !(a

}

inline int operator >(unlim &a,unlim &b)

{

return !(a

}

inline unlim operator +(unlim &x)

{

return x;

}

programm3;

#include

#include

#include

#include

#define COUNT unsigned int

#define TRUE 1

#define FALSE 0

#define ILLEGAL 10

enum

{

PLUS,

MINUS

};

class unlim

{

public:

unlim(char*);

unlim();

unlim(unlim&);

~unlim();

unlim

&operator = (char*),

&operator = (unlim&);

friend int

operator == (unlim&,unlim&),

operator != (unlim&,unlim&),

operator > (unlim&,unlim&),

operator >= (unlim&,unlim&),

operator < (unlim&,unlim&),

operator <= (unlim&,unlim&);

friend unlim

operator + (unlim&), // unary

operator - (unlim&), // unary

operator + (unlim&,unlim&), // binary

operator - (unlim&,unlim&), // binary

operator * (unlim&,unlim&),

abs(unlim&);

friend ostream

&operator << (ostream&,unlim&);

private:

struct descriptor

{

char

*body;

COUNT

len,

HowMany;

};

descriptor

*pv; //pointer to value descriptor

char

sign,

digit(COUNT number);

char &operator [](COUNT i) {return pv->body[i];}

void

init0(), //init by zero

NotDigit(), //message "no digit" & init0

optimize(), //optimize length of body

error(char*); //display error message

};

inline void unlim::error(char *message)

{

cout <<"Unlim class error: "

<

<<"\n";

}

void unlim::init0()

{

(pv->body)=new char;

*(pv->body)=0;

(pv->len)=1;

sign=PLUS;

}

char unlim::digit(COUNT number)

{

if ( number>=(pv->len) )

return ILLEGAL;

char byte=(pv->body)[number/2];

if (number%2==0)

return byte%10;

else

return byte/10;

}

unlim::unlim()

{

pv=new descriptor;

init0();

(pv->HowMany)=1;

}

unlim::~unlim()

{

if ( --(pv->HowMany)==0 )

{

delete pv->body;

delete pv;

}

}

char DecVal(char symbol)

{

if ( isdigit(symbol) )

return symbol-'0';

return ILLEGAL;

}

unlim::unlim(char *string)

{

pv=new descriptor;

(pv->HowMany)=1;

COUNT Length=strlen(string);

if (Length==0)

{

error("Empty string assigned. Value=0");

init0();

return;

}

else

{

COUNT LeftLimit=0;

switch (string[0])

{

case '-':

sign=MINUS;

LeftLimit=1;

break;

case '+':

LeftLimit=1;

default:

sign=PLUS;

}

if (Length-LeftLimit==0)

{

error("Sign without value. Value=0");

init0();

return;

}

else

{

while (string[LeftLimit]=='0')

LeftLimit++;

if ( (Length-=LeftLimit)==0 )

{

init0();

return;

}

COUNT DestLength=Length/2+Length%2;

(pv->body)=new char[DestLength];

for ( COUNT si=Length+LeftLimit-1, ki=0 ; ki

{

char a=DecVal(string[si]);

if (a==ILLEGAL)

{

NotDigit();

return;

}

(pv->body)[ki]=a;

if (si!=LeftLimit)

{

char a=DecVal(string[si-1]);

if (a==ILLEGAL)

{

NotDigit();

return;

}

(pv->body)[ki]+=10*a;

}

}

(pv->len)=Length;

}

}

}

void unlim::NotDigit()

{

error("Not digit symbol in string. String ignored. Value=0");

delete pv->body;

init0();

}

unlim::unlim(unlim &arg)

{

(arg.pv)->HowMany++;

pv=arg.pv;

sign=arg.sign;

}

unlim &unlim::operator=(unlim &arg)

{

(arg.pv)->HowMany++;

if ( --(pv->HowMany)==0 )

{

delete pv->body;

delete pv;

}

pv=arg.pv;

sign=arg.sign;

return *this;

}

unlim &unlim::operator=(char *string)

{

return *this=unlim(string);

}

ostream &operator<<(ostream &s,unlim &x)

{

if (x.sign==MINUS)

s << "-";

for ( COUNT i=((x.pv)->len) ; i>0 ; i-- )

s << int(x.digit(i-1));

return s;

}

int operator!=(unlim &a,unlim &b)

{

if ( (a.pv)->len != (b.pv)->len)

return TRUE;

if (a.sign!=b.sign)

return TRUE;

COUNT length=((a.pv)->len)/2+((a.pv)->len)%2;

for ( COUNT i=0 ; i

if (a[i]!=b[i])

return TRUE;

return FALSE;

}

int operator<(unlim &a,unlim &b)

{

if (a.sign!=b.sign)

return a.sign==MINUS;

if ( (a.pv)->len == (b.pv)->len )

{

COUNT i=((a.pv)->len)-1;

while ( a.digit(i) == b.digit(i) )

{

if (i==0)

return FALSE;

i--;

}

char

aLess= a.digit(i) < b.digit(i),

SignPlus= a.sign==PLUS;

return ( aLess && SignPlus) || ( !aLess && !SignPlus );

}

else

{

char

aShort= (a.pv)->len < (b.pv)->len,

SignPlus= a.sign==PLUS;

return ( aShort && SignPlus ) || ( !aShort && !SignPlus );

}

}

 

inline int operator ==(unlim &a,unlim &b)

{

return !(a!=b);

}

inline int operator <=(unlim &a,unlim &b)

{

return (a

}

inline int operator >=(unlim &a,unlim &b)

{

return !(a

}

inline int operator >(unlim &a,unlim &b)

{

return !(a

}

inline unlim operator +(unlim &x)

{

return x;

}

unlim abs(unlim &x)

{

unlim r=x;

r.sign=PLUS;

return r;

}

unlim operator -(unlim &x)

{

if ( (x.pv)->len==1 && x[0]==0 )

{

unlim y;

return y;

}

unlim y=x;

if (x.sign==PLUS)

y.sign=MINUS;

else

y.sign=PLUS;

return y;

}

void unlim::optimize()

{

COUNT i=pv->len/2+pv->len%2-1;

char optimized=FALSE;

while (pv->body[i]==0)

{

optimized=TRUE;

if (i--==0)

{

init0();

return;

}

}

if (optimized)

{

char *NewBody=new char[++i];

for (COUNT ni=0;ni

NewBody[ni]=pv->body[ni];

delete pv->body;

pv->body=NewBody;

pv->len=(i--)*2;

}

if ( (pv->body[i]/10)==0 && (pv->len%2)==0 )

pv->len--;

}

inline COUNT max (COUNT a,COUNT b)

{

return (a>b)?a:b;

}

unlim operator +(unlim &a,unlim &b)

{

unlim r;

delete (r.pv)->body;

if (a.sign==b.sign)

{

r.sign=a.sign;

COUNT

rlen=max( (a.pv)->len,(b.pv)->len )+1,

alen=(a.pv)->len/2+(a.pv)->len%2,

blen=(b.pv)->len/2+(b.pv)->len%2;

(r.pv)->len=rlen;

rlen=rlen/2+rlen%2;

(r.pv)->body=new char[rlen];

*(r.pv)->body=0;

for (COUNT i=0;i

{

unsigned char sum=( i

r[i]+=sum%100;

r[i+1]=sum/100;

}

if ( r.digit( (r.pv)->len-1 )==0 )

(r.pv)->len--;

}

else

{

unlim

aa=a,

bb=b;

if (abs(a)

{

aa=b;

bb=a;

}

r.sign=aa.sign;

COUNT

rlen=(aa.pv)->len,

blen=(bb.pv)->len/2+(bb.pv)->len%2;

(r.pv)->len=rlen;

rlen=rlen/2+rlen%2;

(r.pv)->body=new char[rlen];

*(r.pv)->body=0;

for (COUNT i=0;i

{

char sub=aa[i]-( i

if (sub<0)

{

r[i+1]=-1;

sub+=100;

}

else

r[i+1]=0;

r[i]=sub;

}

r.optimize();

}

return r;

}

unlim operator -(unlim &a,unlim &b)

{

return a+(-b);

}

unlim operator *(unlim &a,unlim &b)

{

unlim r;

delete (r.pv)->body;

if (a.sign==b.sign)

r.sign=PLUS;

else

r.sign=MINUS;

COUNT

rlen=(a.pv)->len+(b.pv)->len,

alen=(a.pv)->len/2+(a.pv)->len%2,

blen=(b.pv)->len/2+(b.pv)->len%2;

(r.pv)->len=rlen;

rlen=rlen/2+rlen%2;

(r.pv)->body=new char[rlen];

COUNT i;

for (i=0;i

r[i]=0;

for (i=0;i

{

unsigned int

next=0,

mul;

for(COUNT j=0;j

{

next+=r[i+j];

mul=a[i]*b[j]+next;

r[i+j]=mul%100;

next=mul/100;

}

r[i+blen]=next;

}

if ( r.digit((r.pv)->len-1)==0 )

(r.pv)->len--;

if ( r.digit((r.pv)->len-1)==0 )

r.init0();

return r;

}

1Архитектура и строительство
2Астрономия, авиация, космонавтика
 
3Безопасность жизнедеятельности
4Биология
 
5Военная кафедра, гражданская оборона
 
6География, экономическая география
7Геология и геодезия
8Государственное регулирование и налоги
 
9Естествознание
 
10Журналистика
 
11Законодательство и право
12Адвокатура
13Административное право
14Арбитражное процессуальное право
15Банковское право
16Государство и право
17Гражданское право и процесс
18Жилищное право
19Законодательство зарубежных стран
20Земельное право
21Конституционное право
22Конституционное право зарубежных стран
23Международное право
24Муниципальное право
25Налоговое право
26Римское право
27Семейное право
28Таможенное право
29Трудовое право
30Уголовное право и процесс
31Финансовое право
32Хозяйственное право
33Экологическое право
34Юриспруденция
 
35Иностранные языки
36Информатика, информационные технологии
37Базы данных
38Компьютерные сети
39Программирование
40Искусство и культура
41Краеведение
42Культурология
43Музыка
44История
45Биографии
46Историческая личность
47Литература
 
48Маркетинг и реклама
49Математика
50Медицина и здоровье
51Менеджмент
52Антикризисное управление
53Делопроизводство и документооборот
54Логистика
 
55Педагогика
56Политология
57Правоохранительные органы
58Криминалистика и криминология
59Прочее
60Психология
61Юридическая психология
 
62Радиоэлектроника
63Религия
 
64Сельское хозяйство и землепользование
65Социология
66Страхование
 
67Технологии
68Материаловедение
69Машиностроение
70Металлургия
71Транспорт
72Туризм
 
73Физика
74Физкультура и спорт
75Философия
 
76Химия
 
77Экология, охрана природы
78Экономика и финансы
79Анализ хозяйственной деятельности
80Банковское дело и кредитование
81Биржевое дело
82Бухгалтерский учет и аудит
83История экономических учений
84Международные отношения
85Предпринимательство, бизнес, микроэкономика
86Финансы
87Ценные бумаги и фондовый рынок
88Экономика предприятия
89Экономико-математическое моделирование
90Экономическая теория

 Анекдоты - это почти как рефераты, только короткие и смешные Следующий
Янукович считает себя законным президентом Украины. Лечащий врач решил его пока в этом не разубеждать.
Anekdot.ru

Узнайте стоимость курсовой, диплома, реферата на заказ.

Обратите внимание, курсовая по математике "Манипулирование с целыми числами произвольной длины", также как и все другие рефераты, курсовые, дипломные и другие работы вы можете скачать бесплатно.

Смотрите также:


Банк рефератов - РефератБанк.ру
© РефератБанк, 2002 - 2017
Рейтинг@Mail.ru