ПЕРЕЛІК ДИСЦИПЛІН:
  • Адміністративне право
  • Арбітражний процес
  • Архітектура
  • Астрологія
  • Астрономія
  • Банківська справа
  • Безпека життєдіяльності
  • Біографії
  • Біологія
  • Біологія і хімія
  • Ботаніка та сільське гос-во
  • Бухгалтерський облік і аудит
  • Валютні відносини
  • Ветеринарія
  • Військова кафедра
  • Географія
  • Геодезія
  • Геологія
  • Етика
  • Держава і право
  • Цивільне право і процес
  • Діловодство
  • Гроші та кредит
  • Природничі науки
  • Журналістика
  • Екологія
  • Видавнича справа та поліграфія
  • Інвестиції
  • Іноземна мова
  • Інформатика
  • Інформатика, програмування
  • Юрист по наследству
  • Історичні особистості
  • Історія
  • Історія техніки
  • Кибернетика
  • Комунікації і зв'язок
  • Комп'ютерні науки
  • Косметологія
  • Короткий зміст творів
  • Криміналістика
  • Кримінологія
  • Криптология
  • Кулінарія
  • Культура і мистецтво
  • Культурологія
  • Російська література
  • Література і російська мова
  • Логіка
  • Логістика
  • Маркетинг
  • Математика
  • Медицина, здоров'я
  • Медичні науки
  • Міжнародне публічне право
  • Міжнародне приватне право
  • Міжнародні відносини
  • Менеджмент
  • Металургія
  • Москвоведение
  • Мовознавство
  • Музика
  • Муніципальне право
  • Податки, оподаткування
  •  
    Бесплатные рефераты
     

     

     

     

     

     

         
     
    Маніпулювання з цілими числами довільної довжини
         

     

    Інформатика, програмування
    Маніпулювання з цілими числами довільної довжини Постановка задачі:

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

    Модуль, що реалізує цілі числа довільної довжини, і тестова програма написані на мові С + +.

    Для представлення цілих чисел довільної довжини визначено клас 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 ab = 1 a * b = 999999999999999999999999999999999999999999999000000000000000000000000000000000000000000000

    Введено:

    a =- 100000000000000000000000000000000000000000000

    b = 999999999999999999999999999999999999999999999

    Результат:

    a =- 100000000000000000000000000000000000000000000

    b = 999999999999999999999999999999999999999999999

    a = 100000000000000000000000000000000000000000000 + a =- 100000000000000000000000000000000000000000000

    a

    a + b = 899999999999999999999999999999999999999999999 ab =- 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Тестовая програма для класу UNLIMn"

    << "(цілі числа з довільною точністю) 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 =" <

    << "Перевірка виводу, арифметики і порівняння: nn";

    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! = bn";

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

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

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

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

    << "nn ----------------------------------------- --------- nn "

    ;

    )

    )

    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 <

    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)

    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;

    )

         
     
         
    Реферат Банк
     
    Рефераты
     
    Бесплатные рефераты
     

     

     

     

     

     

     

     
     
     
      Все права защищены. Reff.net.ua - українські реферати ! DMCA.com Protection Status