Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > C/C++ программирование > Общие вопросы C/C++
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 18.08.2009, 11:15   #1
zx11
 
Регистрация: 11.06.2009
Сообщений: 8
По умолчанию Задать разрядность числа в конструкторе

Здравствуйте.

Есть проблема - не могу придумать решение, нужно работать с целыми числами разрядностью до пятидесяти знаков. А разрядность необходимо указать в конструкторе класса, вот и думаю как лучше это реализовать. Или как создать тип данных такого размера. Возможно есть другой подход к этой проблеме? Направьте на пусть истинный=) Возможно просто хранить число в виде массива цифр?

Спасибо.

Последний раз редактировалось zx11; 18.08.2009 в 11:23.
zx11 вне форума Ответить с цитированием
Старый 18.08.2009, 11:32   #2
pproger
C++ hater
СтарожилДжуниор
 
Аватар для pproger
 
Регистрация: 19.07.2009
Сообщений: 3,336
По умолчанию

конечно как массив. вот только придется повторно реализовать все математические операции. можно заюзать готовую библиотеку для этих целей - gmp, Либа написана на Си, поэтому можно создать свои классы-оболочки над этой библиотекой. Как там указывается разрядность - не знаю, читай ман (возможно никак не указывается, все основано на связанных списках и тп).
у меня в linux-е она идет в комплекте (ну или зависела от какого то пакета, не могу точно сейчас сказать)
I invented the term Object-Oriented, and I can tell you I did not have C++ in mind. (c)Alan Kay

My other car is cdr.

Q: Whats the object-oriented way to become wealthy?
A: Inheritance
pproger вне форума Ответить с цитированием
Старый 18.08.2009, 12:00   #3
zx11
 
Регистрация: 11.06.2009
Сообщений: 8
По умолчанию

Спасибо за совет по поводу массива, а вот готовую либу я юзать не могу, придётся самому написать. Если кто-то сможет ещё что-то посоветовать буду благодарен.
zx11 вне форума Ответить с цитированием
Старый 18.08.2009, 12:16   #4
pu4koff
Старожил
 
Аватар для pu4koff
 
Регистрация: 22.05.2007
Сообщений: 9,520
По умолчанию

Ключевое слово: "длинная арифметика"
pu4koff вне форума Ответить с цитированием
Старый 18.08.2009, 13:20   #5
LaptevVV
Пользователь
 
Регистрация: 15.08.2009
Сообщений: 37
По умолчанию

Цитата:
Сообщение от zx11 Посмотреть сообщение
Здравствуйте.
Есть проблема - не могу придумать решение, нужно работать с целыми числами разрядностью до пятидесяти знаков. А разрядность необходимо указать в конструкторе класса, вот и думаю как лучше это реализовать. Или как создать тип данных такого размера. Возможно есть другой подход к этой проблеме? Направьте на пусть истинный=) Возможно просто хранить число в виде массива цифр?
Спасибо.
Вот из моей книжки:
Листинг 9.18. Класс «длинных» целых чисел
Код:
class LongLong
{   public:
    // Конструкторы
    LongLong( const string &s );            // инициализация строкой
    LongLong( const long &number = 0 );
// операции c с присваиванием
    LongLong& operator+=( const LongLong &r );
    LongLong& operator-=( const LongLong &r );
    LongLong& operator*=( const LongLong &r );
    LongLong& operator/=( const LongLong &r );
    LongLong& operator%=( const LongLong &r );
// операции без присваивания
    friend LongLong operator+( const LongLong &l, const LongLong &r );
    friend LongLong operator-( const LongLong &l, const LongLong &r );
    friend LongLong operator*( const LongLong &l, const LongLong &r );
    friend LongLong operator/( const LongLong &l, const LongLong &r );
    friend LongLong operator%( const LongLong &l, const LongLong &r );
// ввод – вывод
    friend istream& operator>>( istream &is, LongLong &r );
    friend ostream& operator<<( ostream &os, const LongLong &r );
private:
    vector<char> v;
};
Помимо приведенных дружественных операций, можно добавить еще операции длинных чисел с целыми, например
Код:
friend LongLong operator+( const LongLong &l, const long &r );
friend LongLong operator+( const long &l, const LongLong &r );
Само число находится в поле-контейнере. Каждая цифра — один элемент вектора, младшая цифра расположена в контейнере по младшему индексу. Например, число 765 будет расположено так: v[0]=5, v[1]=6, v[2]=7.
Конструкторов всего два: конструктор копирования создается автоматически, а конструктор без аргументов просто не нужен, так как в конструкторе инициализации задан аргумент по умолчанию. Реализацию покажем на примере конструктора с аргументом-целым (листинг 9.19).
Код:
Листинг 9.19. Конструктор инициализации длинного целого
LongLong::LongLong( const long &number )
{   long t = number, i = 0; 
    char digit;
    while( t > 0 )
    {   digit = t % 10; v.push_back( digit ); t /= 10; }
}
Операции с длинными числами выполняются поэлементно. Покажем реализацию самого простого метода — сложения с присваиванием (листинг 9.20).
Код:
Листинг 9.20. Метод сложения с присваиванием
LongLong& LongLong::operator+=( const LongLong &r )
{   typedef vector<char>::size_type sizeT;
    // определяется размер результата – это размер большего числа
    sizeT size = ( v.size() > r.v.size() ) ? v.size() : r.v.size();   
    unsigned carry = 0, sumDigit;                   // перенос и цифра суммы
    LongLong Summa;                                       // результат-сумма
    for( sizeT i = 0; i < size; i++ )
    {   sumDigit = digit( i ) + r.digit( i ) + carry;
        carry = sumDigit / 10;                    // вычисляем новый перенос
        Summa.v.push_back( sumDigit % 10 );       // добавляем цифру в сумму
    }
    if ( carry ) Summa.v.push_back( carry );  // добавляем последний перенос
    v = Summa.v;
    return *this;
}
Вспомогательная функция digit выдает очередную цифру длинного целого. Ее реализацию можно описать в закрытой части класса:
Код:
char digit( unsigned int i ) const { return i < v.size() ? v[i] : 0; }
Ну, и наконец, реализация функции вывода тоже тривиальна:
Код:
ostream& operator<<( ostream &os, const LongLong &r )
{   for( int i = 0; i < r.v.size(); i++ )
        os << int( r.v[r.v.size() - i - 1] );    // вывод в обратном порядке
    return os;
}
Думаю, разберешься.
Вектор хорош тем, что он во-первых, стандартный. Во-вторых, сам управляет своей памятью.
А если требуется явно задать длину, то в скобках задается.
LaptevVV вне форума Ответить с цитированием
Старый 19.08.2009, 19:01   #6
zx11
 
Регистрация: 11.06.2009
Сообщений: 8
По умолчанию

Всем спасибо за советы.
zx11 вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Узнать разрядность процессора dimonbest Общие вопросы Delphi 16 01.10.2011 09:15
Инициализация массивов в конструкторе. jojahti Общие вопросы C/C++ 7 27.07.2009 13:30
Разрядность чисел obake Microsoft Office Excel 1 24.02.2009 22:46
можно ли автоматически изменить разрядность числа Help Me23 Microsoft Office Excel 1 11.02.2009 15:26
разрядность кода satanatas Помощь студентам 4 11.01.2008 18:15