Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Реализация типа Decimal для БД

2.9K
11 мая 2005 года
pushkin
43 / / 13.09.2004
Мне нужно разработать C++ класс, который из себя будет представлять десятичное число, в котором будет 20 знаков. Знаю, что это можно реализовать с помощью __int64, но для совместимости с другими платформами его не рекомендуется использовать. Слышал про воично-десятичное представление чисел (это когда две цифры хранятся в одном байте). Про способы хранения такого числа мне в принципе все понятно, но мне нужны работающие алгоритмы деления, умножения и прочие.
Может быть у кого-то уже есть готовые решения? Или кто-нибудь знает, откуда надо начать копать?
1.7K
11 мая 2005 года
Envel
206 / / 29.11.2004
Цитата:
Originally posted by pushkin
Мне нужно разработать C++ класс, который из себя будет представлять десятичное число, в котором будет 20 знаков. Знаю, что это можно реализовать с помощью __int64, но для совместимости с другими платформами его не рекомендуется использовать. Слышал про воично-десятичное представление чисел (это когда две цифры хранятся в одном байте). Про способы хранения такого числа мне в принципе все понятно, но мне нужны работающие алгоритмы деления, умножения и прочие.
Может быть у кого-то уже есть готовые решения? Или кто-нибудь знает, откуда надо начать копать?


Это почему __int64 не будет работать на других платформах? Нужно всего лишь использовать компилятор, который это поддерживает. Занимать это будет 8 байт вместо 20 (или 10) на число, а работать будет гораздо быстрее и проще. Такой код будет быстрее выполнятся даже на 8-миразрядном компьютере.
Для того, чтобы составить алгоритм умножения чисел в двоично-десятичном формате достаточно всего лишь вспомнить операции сложения, умножения "в столбик" и деления "уголком".

2.9K
11 мая 2005 года
pushkin
43 / / 13.09.2004
На самом деле проблема тут не только в совместимости, мне хочется создать класс, в конструктор которого я буду передавать количество разрядов или можно сделать шаблон. В __in64 только 20 разрядов вмещается. Что же мне делать, если захочется больше? Базы SQL же больше поддерживают.
Если вас интересует, зачем мне больше, то скажу: я работаю в фирме, которая делает проги для банков. У нас есть набор типов данных, среди которых тип Money - в нем 19 разрядов, среди которых 2 разряда после запятой. Я посмотрел его реализацию недавно - она страшная, ни одного комментария и все потенциально глючное, а мне надо сделать что-то устойчивое, понятное и удобное для доработок.
1.7K
11 мая 2005 года
Envel
206 / / 29.11.2004
Цитата:
Originally posted by pushkin
На самом деле проблема тут не только в совместимости, мне хочется создать класс, в конструктор которого я буду передавать количество разрядов или можно сделать шаблон. В __in64 только 20 разрядов вмещается. Что же мне делать, если захочется больше? Базы SQL же больше поддерживают.
Если вас интересует, зачем мне больше, то скажу: я работаю в фирме, которая делает проги для банков. У нас есть набор типов данных, среди которых тип Money - в нем 19 разрядов, среди которых 2 разряда после запятой. Я посмотрел его реализацию недавно - она страшная, ни одного комментария и все потенциально глючное, а мне надо сделать что-то устойчивое, понятное и удобное для доработок.


А не думал на счет быстрого? Можно оперируя 16/32-хбитными словами обрабатывать эффективно числа длиной больше 64 бит, последовательно.

2.9K
11 мая 2005 года
pushkin
43 / / 13.09.2004
Цитата:
Originally posted by Envel
А не думал на счет быстрого? Можно оперируя 16/32-хбитными словами обрабатывать эффективно числа длиной больше 64 бит, последовательно.


Благодарю за ответы, но они мне вряд ли помогут. Я ищу реальное описание работы с такими числами или сейчас начну сам ваять. С последовательной обработкой я знаком - сложение с запоминанием бита переноса и т. д., но мне нужна поддержка и деления, и умножения. Ну, может, sin() и cos() вычислять не придется - для этой цели можно и к double преобразовать, но вот умножение точно понадобится.

10
11 мая 2005 года
Freeman
3.2K / / 06.03.2004
Цитата:
Originally posted by pushkin
Ну, может, sin() и cos() вычислять не придется - для этой цели можно и к double преобразовать, но вот умножение точно понадобится.


Все до не могу просто. Если по твоим словам задача сводится просто к работе с целыми числами высокой разрядности, можешь поискать библиотеки, использующиеся в шифровании. Там ведь ключи до 4096 бит бывают.

Кстати, вопрос уже не раз поднимался на форуме, и даже ссылки давали. Ищи.

425
12 мая 2005 года
sq_deep
498 / / 18.02.2005
Цитата:
Originally posted by Freeman
Все до не могу просто. Если по твоим словам задача сводится просто к работе с целыми числами высокой разрядности, можешь поискать библиотеки, использующиеся в шифровании. Там ведь ключи до 4096 бит бывают.

Кстати, вопрос уже не раз поднимался на форуме, и даже ссылки давали. Ищи.

Не хотел отвечать, потому что [COLOR=blue]полностью согласен с Freemanом[/COLOR], но всё-таки не удержался и добавил. Зря, наверно...

Если хочется попрограммировать, то знаю идею. Двоично-десятичная арифметика реализована в архитектуре IBM mainframe. Там это делается примерно так. (В деталях могу ошибаться, потому что уже давно не общался с такими машинами.)

Имеются упакованные числа. Они используются для хранения и обмена информацией.
Один десятичный знак занимает 4 бита. Для этого используются двоичные числа от 0000 до 1001.
Младшие десятичные знаки предшествуют старшим.
Знак числа находится в конце последовательности и представляется кодами 1010 для плюса и 1011 для минуса.
Для дробей используется десятичный разделитель с кодом 1100.
Коды 1101 и 1111 не используются.
Число занимает целое количество байт. При необходимости в старшем разряде добавляется 0.

Имеются распакованные числа. Они используются для вычислений.
Каждый значащий полубайт превращается в байт, десятичный разделитель выкидывается.

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

Умножение и деление выполняется, как отметил уже Envel, над значащими цифрами "в столбик".

Синусы, косинусы и иже с ними в двоично-десятичном представлении не поддерживаются.

Максимальная точность представления — 255 десятичных знаков.

Работает крайне медленно.

Попробуйте реализовать такое же, если хотите, или найдите описание алгоримтов от IBM. Я думаю, они не секретны. Однако, портировать их не удастся, потому что они написаны на каком-то специальном ассемблере, предназначенном только для mainframe.

Удачи вам, г-н pushkin.

2.9K
12 мая 2005 года
pushkin
43 / / 13.09.2004
Спасибо за ваш ответ, тов. sq_deep, он для меня многое прояснил. Буду копать те исходники, что у меня уже есть. Они написаны на C и реализуют операции с такими числами. Я думал, что это можно реализовать как-то красиво, но, видимо, красиво не получится - там ни одного комментария и все в переменных типа i,j,k,m,n,o,... и еще там куча вложенных циклов, так что разобраться с этой кашей я уже не надеюсь, а хотелось бы - ведь если я буду это просто использовать, то я не смогу гарантировать стабильность работы моих программ :(
Если кто-нибудь хочет заиметь эти исходники, оставляйте свой e-mail - я вам их вышлю :)
10
12 мая 2005 года
Freeman
3.2K / / 06.03.2004
Цитата:
Originally posted by pushkin
Они написаны на C и реализуют операции с такими числами.


К слову сказать, в ассемблере x86 есть специальные команды для работы с BCD-числами. Только уже не помню, что конкретно они могут.

425
12 мая 2005 года
sq_deep
498 / / 18.02.2005
А вот тут ещё гляньте.
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог