Small Decimal в .Net
От: ylem  
Дата: 28.01.21 09:49
Оценка:
Астрологи объявили неделю вопросов про торговые данные

Нет ли общепринятого в .Net способа компактно харнить и опрерировать Decimal, если 128bit не нужно? Хватило бы по int32 слева от точки и int32 справа.
Складывать, умножать, делить нужно редко.
Нужно часто сранивать и бинарно десериализовать.

Для сериализации попробовал messagepack. Он Decimal сохраняет буквально в строковов представленн. Видимо, так в общем случае компактней, но работает совсем не быстро.
Отредактировано 28.01.2021 10:24 ylem . Предыдущая версия .
Re: Small Decimal в .Net
От: karbofos42 Россия  
Дата: 28.01.21 11:24
Оценка: +2
Здравствуйте, ylem, Вы писали:

Y>Астрологи объявили неделю вопросов про торговые данные


Y>Нет ли общепринятого в .Net способа компактно харнить и опрерировать Decimal, если 128bit не нужно? Хватило бы по int32 слева от точки и int32 справа.

Y>Складывать, умножать, делить нужно редко.
Y>Нужно часто сранивать и бинарно десериализовать.

Y>Для сериализации попробовал messagepack. Он Decimal сохраняет буквально в строковов представленн. Видимо, так в общем случае компактней, но работает совсем не быстро.


Int64 и работать с "копейками", а не "рублями"?
Re[2]: Small Decimal в .Net
От: ylem  
Дата: 28.01.21 11:33
Оценка:
K>Int64 и работать с "копейками", а не "рублями"?
Копейки, к сожалению, дробные. И для разных "активов" кол-во значащих знаков разное.
Считаем, что половина десятиных знаков на копейки, половина на рубли?
Re[3]: Small Decimal в .Net
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 28.01.21 11:39
Оценка:
Здравствуйте, ylem, Вы писали:

K>>Int64 и работать с "копейками", а не "рублями"?

Y>Копейки, к сожалению, дробные. И для разных "активов" кол-во значащих знаков разное.
Y>Считаем, что половина десятиных знаков на копейки, половина на рубли?

Тогда Int64 под целые и int под дробную
и солнце б утром не вставало, когда бы не было меня
Re[3]: Small Decimal в .Net
От: karbofos42 Россия  
Дата: 28.01.21 11:58
Оценка:
Здравствуйте, ylem, Вы писали:

K>>Int64 и работать с "копейками", а не "рублями"?

Y>Копейки, к сожалению, дробные. И для разных "активов" кол-во значащих знаков разное.
Y>Считаем, что половина десятиных знаков на копейки, половина на рубли?

Всегда можно выдумать свои полукопейки или еще какую единицу измерения, лишь бы дробные числа перевести в целые и в них уже хранить и выполнять арифметические операции.
Если именно пополам поделить, то тут уже лучше сразу брать два отдельных Int32 и писать для них свою арифметику.
Re[3]: Small Decimal в .Net
От: Mihas  
Дата: 28.01.21 11:59
Оценка:
Здравствуйте, ylem, Вы писали:

Y>Копейки, к сожалению, дробные. И для разных "активов" кол-во значащих знаков разное.

Y>Считаем, что половина десятиных знаков на копейки, половина на рубли?
Мой вариант. Создать класс и хранить в нем:
— Int64 — значение в копейках
— Int32 — количество копеек в одном рубле
Обвесить класс операторами приведения к стандартным числовым типам.
Re[4]: Small Decimal в .Net
От: _NN_ www.nemerleweb.com
Дата: 28.01.21 12:24
Оценка: +1
Здравствуйте, Serginio1, Вы писали:

S>Здравствуйте, ylem, Вы писали:


K>>>Int64 и работать с "копейками", а не "рублями"?

Y>>Копейки, к сожалению, дробные. И для разных "активов" кол-во значащих знаков разное.
Y>>Считаем, что половина десятиных знаков на копейки, половина на рубли?

S>Тогда Int64 под целые и int под дробную


И получаем 12 байт вместо 16-ти.
Учитывая выравнивание на 8 байт и количество работы да и возможности оптимизации, вопрос стоит ли овчинка выделки остаётся открытым.

Не спорю, что возможно и стоит, однако нужно подходит с умом к делу.
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re[5]: Small Decimal в .Net
От: ylem  
Дата: 28.01.21 13:01
Оценка:
_NN>И получаем 12 байт вместо 16-ти.
_NN>Учитывая выравнивание на 8 байт и количество работы да и возможности оптимизации, вопрос стоит ли овчинка выделки остаётся открытым.

12 вместо 16 выделки не стоит точно. Особенно с учетом вероятной потери в скорости.
Меня больше "возмутило", что сериализатор, который выроде как очень быстрый, в моем случае оказался тормоз тормозом.
Пусть пока в памяти будет Decimal, а в Dto структура Int32+Int32.
Re[6]: Small Decimal в .Net
От: _NN_ www.nemerleweb.com
Дата: 28.01.21 13:08
Оценка:
Здравствуйте, ylem, Вы писали:

_NN>>И получаем 12 байт вместо 16-ти.

_NN>>Учитывая выравнивание на 8 байт и количество работы да и возможности оптимизации, вопрос стоит ли овчинка выделки остаётся открытым.

Y>12 вместо 16 выделки не стоит точно. Особенно с учетом вероятной потери в скорости.

Y>Меня больше "возмутило", что сериализатор, который выроде как очень быстрый, в моем случае оказался тормоз тормозом.
Y>Пусть пока в памяти будет Decimal, а в Dto структура Int32+Int32.

В protobuf тоже предлагают просто хранить int64 + int32: https://docs.microsoft.com/en-us/dotnet/architecture/grpc-for-wcf-developers/protobuf-data-types
Немного кода и получаем тип, который умеет преобразовываться неявно в decimal.
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re[3]: Small Decimal в .Net
От: Ночной Смотрящий Россия  
Дата: 28.01.21 13:47
Оценка:
Здравствуйте, ylem, Вы писали:

K>>Int64 и работать с "копейками", а не "рублями"?

Y>Копейки, к сожалению, дробные.

Храни в сотых долях копейки. Это общепринятая штука и она прописана во многих нормативных документах.

Y> И для разных "активов" кол-во значащих знаков разное.


Если в самом точном случае хватает 64бит — не вижу проблем. Если не хватает — придется придумать что то типа псевдоплавучки и выделить под экспоненту несколько бит. Но арифметика, конечно, заметно усложнится.
... << RSDN@Home 1.3.17 alpha 5 rev. 62>>
Re[5]: Small Decimal в .Net
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 28.01.21 14:50
Оценка:
Здравствуйте, _NN_, Вы писали:
S>>Тогда Int64 под целые и int под дробную

_NN>И получаем 12 байт вместо 16-ти.

_NN>Учитывая выравнивание на 8 байт и количество работы да и возможности оптимизации, вопрос стоит ли овчинка выделки остаётся открытым.

_NN>Не спорю, что возможно и стоит, однако нужно подходит с умом к делу.


Тогда 2 Int64. В исходном было 2 инта. Только тогда вопрос а в чем выигрышь по сравнению с decimal?
и солнце б утром не вставало, когда бы не было меня
Re: Small Decimal в .Net
От: Sinclair Россия https://github.com/evilguest/
Дата: 28.01.21 16:38
Оценка: 4 (1)
Здравствуйте, ylem, Вы писали:
Y>Нет ли общепринятого в .Net способа компактно харнить и опрерировать Decimal, если 128bit не нужно? Хватило бы по int32 слева от точки и int32 справа.
Общепринятого — нет.
Но можно навелосипедить свой. Точно ли вам нужно все 64 бита точности? Если да, то плохо с выравниванием — вам нужно записать число от 0 до 18, чтобы обозначить позицию десятичной точки, то есть потратить ещё 5 бит, что даёт в сумме 69 бит.
Если нет, то могу предложить следующее:
— биты №64..61: scale — 4-разрядное целое число от 0 до 15
— биты №60..0: 60-разрядное целое число со знаком
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re: Small Decimal в .Net
От: · Великобритания  
Дата: 28.01.21 17:05
Оценка:
Здравствуйте, ylem, Вы писали:

Y>Астрологи объявили неделю вопросов про торговые данные


Y>Нет ли общепринятого в .Net способа компактно харнить и опрерировать Decimal, если 128bit не нужно? Хватило бы по int32 слева от точки и int32 справа.

32 бита справа это одна миллиардная. Значит используй int64 и трактуй это как 9 знаков, нано-доллары т.е.
value / 1_000_000_000 это целая часть
value % 1_000_000_000 это дробная часть
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Отредактировано 28.01.2021 17:33 · . Предыдущая версия .
Re: Small Decimal в .Net
От: Kolesiki  
Дата: 28.01.21 17:13
Оценка:
Здравствуйте, ylem, Вы писали:

Y>Нет ли общепринятого в .Net способа компактно харнить и опрерировать Decimal, если 128bit не нужно? Хватило бы по int32 слева от точки и int32 справа.


Как забавный вариант, так и храни как два целых! Целую часть — в одно, дробную умножаешь на 1000000, округляешь и в другое целое. А для операций конвертируешь обратно в decimal.
Re[2]: Small Decimal в .Net
От: Ночной Смотрящий Россия  
Дата: 28.01.21 20:02
Оценка:
Здравствуйте, Sinclair, Вы писали:

=S>Если нет, то могу предложить следующее:
S>- биты №64..61: scale — 4-разрядное целое число от 0 до 15
S>- биты №60..0: 60-разрядное целое число со знаком

Поздравляю, ты изобрел плавучую точку
... << RSDN@Home 1.3.17 alpha 5 rev. 62>>
Re[3]: Small Decimal в .Net
От: Sinclair Россия https://github.com/evilguest/
Дата: 29.01.21 02:44
Оценка:
Здравствуйте, Ночной Смотрящий, Вы писали:
НС>Поздравляю, ты изобрел плавучую точку
Ну да, только в IEEE scale описывает степени двойки, а в decimal — десятки.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[4]: Small Decimal в .Net
От: Mihas  
Дата: 29.01.21 06:19
Оценка: +1
Здравствуйте, Ночной Смотрящий, Вы писали:

НС>Храни в сотых долях копейки. Это общепринятая штука и она прописана во многих нормативных документах.

Есть примеры рекомендаций под рукой?
Среди валют мне на глаза попадались примеры с 4-мя знаками после запятой. А в живых проектах видел запас до 5 знаков.
Re[5]: Small Decimal в .Net
От: Ночной Смотрящий Россия  
Дата: 29.01.21 14:32
Оценка:
Здравствуйте, Mihas, Вы писали:

НС>>Храни в сотых долях копейки. Это общепринятая штука и она прописана во многих нормативных документах.

M>Есть примеры рекомендаций под рукой?

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

M>Среди валют мне на глаза попадались примеры с 4-мя знаками после запятой. А в живых проектах видел запас до 5 знаков.


Требования должен уточнять не разработчик, а продакт. У вас есть продакт/бизнес-аналитик или хотя бы проджект? Ты этот вопрос им задавал?
... << RSDN@Home 1.3.17 alpha 5 rev. 62>>
Re: Small Decimal в .Net
От: Xander Zerge Россия www.zerge.com
Дата: 29.01.21 16:57
Оценка: 4 (1)
Здравствуйте, ylem, Вы писали:

Y>Астрологи объявили неделю вопросов про торговые данные

Y>Нет ли общепринятого в .Net способа компактно харнить и опрерировать Decimal, если 128bit не нужно? Хватило бы по int32 слева от точки и int32 справа.

Не очень понятна решаемая задача.

Если компактно хранить цены сделок, то я сохраняю отдельно шаг цены, который фиксирован для инструмента, а цены сделок — в целом числе шагов.
Ну и так как цены сделок, следующих друг за другом отличаются буквально на несколько шагов, для каждой сделки сохраняю разницу с предыдущей, и для этого в 99% случаев хватает одного байта.

Если для оперирования ценами-объёмами, то тут достаточно типа double. Сам раньше использовал decimal, но проанализировав вычислительные затраты, перешёл на double.
Точности хватает с запасом, и значения, вычислямые для технических индикаторов ничем практически не отличаются, что в decimal, что в double, и уж тем более мизерная разница никак не влияет на формируемые сигналы, а скорость расчёта с double в разы выше.
Серёжа Новиков,
программист
Re[2]: Small Decimal в .Net
От: ylem  
Дата: 29.01.21 20:09
Оценка:
Это для стакана. Большого кол-ва снимков стаканов. В стакане цены отличаются тоже на шаг цены, спасибо!
Индикаторов не предвидится, так что вычислений вроде бы не будет тоже.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.