Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: 1 2 [Все]   Вниз
  Печать  
Автор Тема: Класс сверхбольших целых чисел  (Прочитано 36284 раз)
0 Пользователей и 1 Гость смотрят эту тему.
Dr.Yevhenius
Опытный

ua
Offline Offline
Пол: Мужской

« : 28-05-2010 09:26 » 

Добрый день!
Попробовал записать __int64 в cout. Не получилось. Поэтому возник вопрос: можно ли вообще вывести __int64 с помощью cout'а?
Вот код:
Код:
std::ostream& operator<<(std::ostream& out, intx& number)
{
__int64 buffer = 0;
for(int i = number.getSize() - 1; i >= 0; --i)
{
buffer = buffer<<8;
buffer += number.byteAt(i);
}
out << buffer; // error C2593: 'operator <<' is ambiguous
return out;
}
« Последнее редактирование: 29-05-2010 14:49 от Алексей1153++ » Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #1 : 28-05-2010 09:40 » 

как-нибудь так ))

__int64 i64;
строка . Format("%I64",i64);
cout << строка;


или побайтно хочешь ? В виде хексов ?
Записан

Dr.Yevhenius
Опытный

ua
Offline Offline
Пол: Мужской

« Ответ #2 : 28-05-2010 09:51 » 

Если понимать под "строка" - обьект класса String, то это подойдет разве что для языка C#, а у меня - C++.
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #3 : 28-05-2010 09:53 » 

YevhenUA, при чём тут шарп

это именно для форматирования в поток. Просто я обычно CString (MFC) использую, поэтому пример с std::string с ходу написать не смогу
Записан

Dr.Yevhenius
Опытный

ua
Offline Offline
Пол: Мужской

« Ответ #4 : 28-05-2010 09:55 » 

Про CString до сих пор вообще не знал. Улыбаюсь Спасибо, буду пробовать.
Записан
Антон (LogRus)
Глобальный модератор

ru
Offline Offline
Пол: Мужской
Внимание! Люблю сахар в кубиках!


WWW
« Ответ #5 : 28-05-2010 14:16 » 

забудь про эту пакость
у меня всё нормально собирается, что за компилятор?
Записан

Странно всё это....
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #6 : 28-05-2010 15:13 » 

LogRus, с чего вдруг это пакость то Улыбаюсь Очень удобный класс. Я только не совсем понял, зачем он автору топика, если тот не использует MFC
Записан

Dr.Yevhenius
Опытный

ua
Offline Offline
Пол: Мужской

« Ответ #7 : 28-05-2010 17:18 » 

Я только не совсем понял, зачем он автору топика, если тот не использует MFC
Наугад сказано, но верно Ага

LogRus, о компиляторе информацию не нашел, а вообще Microsoft Visual Studio 6.0.

+
Я только не совсем понял, зачем он автору топика, если тот не использует MFC
Это же твой вариант Жжешь , а ничего другого мне никто не предложил.
« Последнее редактирование: 28-05-2010 17:25 от YevhenUA » Записан
Dr.Yevhenius
Опытный

ua
Offline Offline
Пол: Мужской

« Ответ #8 : 28-05-2010 17:21 » 

Можно тему продолжать к решению или удалять: к сожалению __int64 мне не подходит по заданию.  Жаль
« Последнее редактирование: 28-05-2010 17:27 от YevhenUA » Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #9 : 28-05-2010 17:31 » 

YevhenUA, я так и не понял, используешь ты MFC или нет ))) Если нет, то так отформатировать можно и std::string.

а какой тип подходит ? Почему забраковал __int64 ? )
Записан

Dr.Yevhenius
Опытный

ua
Offline Offline
Пол: Мужской

« Ответ #10 : 28-05-2010 17:35 » 

MFC не использую.
__int64 не подходит, так как он имеет 8 байтов (я так понимаю), а размер intx может достигать 1000000 байтов и более.

Решение (еще одно)(без строк) на даный момент:
Код:
	__int64 i = 55;
printf("%I64d", i);
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #11 : 28-05-2010 17:36 » 

вот такой код позволяет форматировать string (код не мой, я нашёл и лишь подредактировал)
Код:
	void st_FormatStringArgList(std::string& s,DWORD dwdResLenToTryFirst,const char *fmt, va_list args)
{
if(s.size()!=0)
{
s="";
}

if(!fmt)
{
return;
}

DWORD length=max(dwdResLenToTryFirst,256);
s.resize(length,0);

for(int result=-1;result==-1 && length;length<<=1)
{
s.resize(length,0);
if(s.size()!=length)
{
s="";
break;
}

//result=_vsnprintf...
result=_vsnprintf_s(
&s[0],
s.size()*sizeof(s[0]),
s.size(),
fmt,
args
);
}
}

void st_FormatString(std::string& s,const char *fmt, ...)
{
va_list args;
va_start(args, fmt);
st_FormatStringArgList(s,16,fmt,args);
va_end(args);
}

void st_FormatString(DWORD dwdResLenToTryFirst,std::string& s,const char *fmt, ...)
{
va_list args;
va_start(args, fmt);
st_FormatStringArgList(s,dwdResLenToTryFirst,fmt,args);
va_end(args);
}

дело за малым:
Код:
#include <string>

std::string s;
__int64 i64;
st_FormatString(s,"%I64",i64);
cout<<s;

(не тестировал)
Записан

Dr.Yevhenius
Опытный

ua
Offline Offline
Пол: Мужской

« Ответ #12 : 28-05-2010 17:37 » 

Виглядит строшшшшно. Отлично
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #13 : 28-05-2010 17:37 » 

Цитата
а размер intx может достигать 1000000 байтов и более
дык, массив тебе нужен Улыбаюсь
Расскажи хоть задачу. А то во тьме тыкаемся
Записан

Dr.Yevhenius
Опытный

ua
Offline Offline
Пол: Мужской

« Ответ #14 : 28-05-2010 17:39 » 

Создать новый целый тип (он же intx), размер которого не определен заранее. Должен поддерживать операции + - * / % а также преобразование в примитивные типы: char, short int, int, float и т. п.
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #15 : 28-05-2010 17:43 » 

а, вон чего. Ну, тут сложение и вычитание более или менее просто, а вот с умножением и делением надо поискать алгоритм )

А массив нужен динамический. Или можно vector применить
Записан

Finch
Спокойный
Администратор

il
Offline Offline
Пол: Мужской
Пролетал мимо


« Ответ #16 : 28-05-2010 17:47 » 

Алгоритм умножения и деления давно известен. Его проходят где то во 2 классе обычной школы Улыбаюсь
Записан

Не будите спашяго дракона.
             Джаффар (Коша)
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #17 : 28-05-2010 17:49 » 

Finch, просто тупо много складывать и отнимать - это довольно долго ))) Разве что "столбик" реализовать

чем автору темы и предлагается заняться )
Записан

Finch
Спокойный
Администратор

il
Offline Offline
Пол: Мужской
Пролетал мимо


« Ответ #18 : 28-05-2010 17:51 » 

Я о том и говорю, что столбик никто еше не отменял. А тем более, если умножение делать в двоичном коде. Там вообше получается красота.
Записан

Не будите спашяго дракона.
             Джаффар (Коша)
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #19 : 28-05-2010 17:54 » 

имхо, в двоичном виде неэффективно по скорости будет. Лучше применить BCD формат (одна десятичная цифра в байте) или упакованный BCD (одна цифра в тетраде)

жаль только, что C++ не поддерживает такие типы напрямую (а сам процессор вроде умеет простые операции с BCD производить - если писать на ассемблере, эти возможности резко становятся доступны Отлично )
« Последнее редактирование: 28-05-2010 17:58 от Алексей1153++ » Записан

Finch
Спокойный
Администратор

il
Offline Offline
Пол: Мужской
Пролетал мимо


« Ответ #20 : 28-05-2010 18:02 » 

Алексей1153++, Если делать в двоичной алгебре умножение, то там так такового умножения вообше не будет. Сдвиг влево и сложение, вот основные операции.
Записан

Не будите спашяго дракона.
             Джаффар (Коша)
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #21 : 28-05-2010 18:12 » 

это когда без "столбика" , а так всё равно придётся несколько раз сдвинуть - и всё равно каждый байт. А операция сложения/вычитания по скорости такая же. Опять же - флаг переноса в C++ не посмотреть

Догадки всё, конечно, сам на C++ "столбик" не реализовывал. Практика бы всё расставила по местам ))
Записан

Finch
Спокойный
Администратор

il
Offline Offline
Пол: Мужской
Пролетал мимо


« Ответ #22 : 28-05-2010 18:14 » 

Я как-то реализовывал класс сверх больших чисел.  В том задании было, что числа положительны и должны содержать не менее 350 десятичных чисел. С точностью до единици.  Лучшего метода, чем столбик, я не надумал.
« Последнее редактирование: 28-05-2010 18:17 от Finch » Записан

Не будите спашяго дракона.
             Джаффар (Коша)
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #23 : 28-05-2010 18:19 » 

нет,  сам столбик сомнения не вызывает, вопрос в том, что выбирать для соотношения "скорости работы"/"занимаемая память" ))

bin даст выигрыш в объёме и простоте, а BCD - в скорости (но утверждение не на 100%, как я выше уже говорил... )
Записан

Dr.Yevhenius
Опытный

ua
Offline Offline
Пол: Мужской

« Ответ #24 : 29-05-2010 14:46 » 

Создал два файла: H-файл, в котором описан класс и CPP-файл, в котором находится реализация. Но когда пишу
Код:
#include "intx.h"
Microsoft Visual Studio 6.0 не соображает сам подключать intx.cpp. Поэтому решил проблему следующим образом:
Код:
class intx
{
...
};
#include "intx.cpp"
Но я засомневался, что такой способ "нормальный" Улыбаюсь . Хочу у вас спросить: есть ли для этого какая-нибудь специальная директива или команда?
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #25 : 29-05-2010 14:52 » 

YevhenUA,
1) *.H и *.CPP надо добавить в дерево проекта.

2) #include "intx.cpp" - это убрать

3) если используются прекомпилированные заголовки, то в САМОМ начале CPP-файла написать строку
#include "stdafx.h"
а в САМОМ конце файла CPP должна быть хотя бы одна пустая строка


Записан

Dr.Yevhenius
Опытный

ua
Offline Offline
Пол: Мужской

« Ответ #26 : 29-05-2010 15:00 » 

Добавил файлы к проекту. Работает. Спасибо.

З.Ы. Минуту понять не мог, что означает слово "САМОМ" (читал по-английски).
Записан
Dr.Yevhenius
Опытный

ua
Offline Offline
Пол: Мужской

« Ответ #27 : 29-05-2010 15:16 » 

Всё было хорошо, пока не начал тестировать.
Workplace.cpp
Код:
#include <stdafx.h>
#include <stdlib.h>

#include "dinamic.h"
using namespace quark;

int main(int argc, char* argv[])
{
printf("DINAMIC test...\n");

dinamic<int> d;

system("pause");
return 0;
}

dinamic.h
Код:
#ifndef QUARK_DINAMIC
#define QUARK_DINAMIC

namespace quark
{

template <typename T>
class dinamic
{
public:
dinamic();
dinamic(T & variable);
~dinamic();
protected:
T* var;
};

}

#endif // QUARK_DINAMIC

dinamic.cpp
Код:
#include <stdafx.h>
#include "dinamic.h"

template <typename T>
quark::dinamic<T>::dinamic(): var(0)
{
}

template <typename T>
quark::dinamic<T>::dinamic(T & variable): var(0)
{
var = &variable;
}

template <typename T>
quark::dinamic<T>::~dinamic()
{
delete T;
T = 0;
}

Ошибки:
Цитата
Workplace.obj : error LNK2001: unresolved external symbol "public: __thiscall quark::dinamic<int>::~dinamic<int>(void)" (??1?$dinamic@H@quark@@QAE@XZ)
Workplace.obj : error LNK2001: unresolved external symbol "public: __thiscall quark::dinamic<int>::dinamic<int>(void)" (??0?$dinamic@H@quark@@QAE@XZ)
Debug/Workplace.exe : fatal error LNK1120: 2 unresolved externals
А черт его знает...
Записан
Dr.Yevhenius
Опытный

ua
Offline Offline
Пол: Мужской

« Ответ #28 : 29-05-2010 15:18 » 

Линковщик не видит dinamic.cpp
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #29 : 29-05-2010 15:21 » 

реализации шаблонных функций надо разместить в H файле
Записан

Dr.Yevhenius
Опытный

ua
Offline Offline
Пол: Мужской

« Ответ #30 : 29-05-2010 15:21 » 

Это правило или совет?
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #31 : 29-05-2010 15:23 » 

скорее правило )) Почему-то не желает иначе линковаться
Записан

Вад
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #32 : 29-05-2010 15:39 » 

Это правило, пока компиляторы не научились поддерживать экспорт реализаций шаблонов.
Если немного поразмыслить о том, как реализуется инстанцирование шаблонов, то мотивация существующего решения достаточно очевидна.
Как, впрочем, и явный экспорт определения шаблона, предписываемый стандартом.
Записан
Dr.Yevhenius
Опытный

ua
Offline Offline
Пол: Мужской

« Ответ #33 : 29-05-2010 18:19 » 

Пречитав еще раз 13 ответ, а именно
дык, массив тебе нужен
хочу сказать, что я и не собирался использовать __int64 для хранения данных, если ты об этом. Он мне нужен был для только вывода хранимого числа, хотя даже так идея неподходящая.
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #34 : 30-05-2010 06:31 » 

__int64 - это массив из 8 байтов. Разница невеликая Улыбаюсь

кстати, из BCD формата выводить на экран тоже проще всего будет
« Последнее редактирование: 30-05-2010 06:36 от Алексей1153++ » Записан

RXL
Технический
Администратор

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #35 : 30-05-2010 07:40 » 

Леш, зато арифметика BCD сложнее и много медленней. Например, команды x86 для коррекции BCD после арифметических операций работают всего с одним нибблом.
Я  как-то разбирался с форматом DECIMAL в MySQL (может хранить до 65-и знаков) и нашел, что там каждые 4 десятичных знака кодируются как 2-х байтовое двоичное целое (unsigned short). Думаю, что такой выбор сделан не с проста.
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
Dr.Yevhenius
Опытный

ua
Offline Offline
Пол: Мужской

« Ответ #36 : 30-05-2010 09:52 » 

__int64 - это массив из 8 байтов. Разница невеликая Улыбаюсь
Ради 8 байтов я буду исполизовать __int64 Улыбаюсь

BCD-формат - это хранение в каждом байте числа от 0 до 9, я правильно понимаю?
Записан
RXL
Технический
Администратор

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #37 : 30-05-2010 09:56 » 

YevhenUA, не в байте, а в ниббле (4 бита). В остальном - правильно.
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #38 : 30-05-2010 11:40 » 

если хранить в одном байте одну цифру, будет шустро Улыбаюсь
Записан

RXL
Технический
Администратор

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #39 : 30-05-2010 14:53 » 

Заглянул в заголовки библиотеки GMP (библиотека больших чисел): для хранения используется либо 32-, либо 64-битные целые.
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
Антон (LogRus)
Глобальный модератор

ru
Offline Offline
Пол: Мужской
Внимание! Люблю сахар в кубиках!


WWW
« Ответ #40 : 31-05-2010 03:47 » 

Лично мне нравится формат используемый в Oracle
http://my-oracle.it-blogs.com.ua/post-272.aspx
http://www.oracle.com/global/ru/oramag/julyaugust2002/admin_number.html

Что же касается шаблонов, то тут всё просто, т.к. не было определения функций(конструктора и деструктора в данном случае) в заголовочном файле, то компилятор резонно предположил, что ему предоставят тела методов на этапе линковки, но тела методов создаются при инстанцировании, т.е. при попытке их использовать из не шаблонного кода. Инстанцирование по известной причине не произошло, но это вполне допускается стандартом, в данном случае надо было просто выполнить явное инстанцирование шаблона с нужными параметрами в cpp файле в котором есть реализация методов.
Записан

Странно всё это....
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #41 : 31-05-2010 04:34 » 

LogRus, а покажи пример... То есть там надо было создать некий фуфельный левый класс, где явно использовать фсе функции ?
Записан

Антон (LogRus)
Глобальный модератор

ru
Offline Offline
Пол: Мужской
Внимание! Люблю сахар в кубиках!


WWW
« Ответ #42 : 31-05-2010 05:00 » 

Ну не так всё страшно Улыбаюсь для этих целей есть специальная инструкция, которую обычно ставят после всех определений класса или в конце файла (кому как удобней, мне удобней 2-е)
Код:
template class Dinamic<int>; 
собственно и всего делов-то, можно так делать для каждого метода по отдельности, можно создать для каждого метода отдельный файл, ну и т.д. и т.п.

собственно это всё есть в разделе 10.5 Explicit Instantiation книги: Д. Вандервуд и Н. Джосатис "Шаблоны C++. Полное руководство"
PS: могу выслать если нужно
Записан

Странно всё это....
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #43 : 31-05-2010 05:31 » 

давай, пришли )
Переименовался ? Ага
Записан

Антон (LogRus)
Глобальный модератор

ru
Offline Offline
Пол: Мужской
Внимание! Люблю сахар в кубиках!


WWW
« Ответ #44 : 31-05-2010 05:39 » 

давай, пришли )
Переименовался ? Ага
Выслал.
Угу, надоело.
Записан

Странно всё это....
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #45 : 31-05-2010 05:54 » 

Спасибо ) Дома почитаю
Записан

Страниц: 1 2 [Все]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines