Типы чисел в DSL
От: Alekzander  
Дата: 01.12.23 21:18
Оценка:
Возник вопрос на стыке проектирования, UX и БД )) Требуются ваши мнения.

Мне нужно спроектировать DSL. С одной стороны, он должен быть строго типизирован (это требование), а с другой — этот тип появится на уровне GUI для массовых пользователей. А их, по возможности, хотелось бы не грузить разницей между int и double (не говоря про потерю точности), а дать им вместо этого некий универсальный тип number. С другой стороны, возможно, стоит один раз научить юзеров разнице между int и double, чем разруливать миллион неоднозначностей.

Что еще хуже, иногда возможно хранение в переменных сумм денег. Как я знаю, в таких случаях принято использовать третий тип: с эмуляцией вещественности через целые (нужны гарантии, что 0.1 + 0.2 == 0.3). Но три разных типа для чисел — для юзеров это уже будет перебор. Или нет? Может, как раз дать им кучу типов и пусть сами несут ответственность за сходимость балансов? ))

Сами значения будут храниться в sqlite (он лёгкий, встраиваемый и опенсорсный, но если есть альтернативы, можно рассмотреть). Доступ к ним планируется только через слой этого DSL'я, хотя, конечно же, желательно сохранить возможность обработки (в т.ч. вычислений) через запросы. Я так понимаю, придётся все агрегирующие функции писать самому?

Итак, что посоветуете для внутреннего представления чисел в памяти и хранения в sqlite? И какими типами это всё оформить для юзеров?
Re: Типы чисел в DSL
От: IT Россия linq2db.com
Дата: 01.12.23 23:58
Оценка: 3 (1)
Здравствуйте, Alekzander, Вы писали:

A>Итак, что посоветуете для внутреннего представления чисел в памяти и хранения в sqlite? И какими типами это всё оформить для юзеров?


На вскидку я бы ещё тип percent рассмотрел. А вообще, с бы этот вопрос задал тем, кто шарит в 1C. Всё же там накоплен ахренительно немалый опыт по данной теме.

По поводу sqlite, то желательно подробности. Если предполагается минимум данных и нежелательность возни с установками дополнительного софта, то sqlite нормальный выбор.
Если нам не помогут, то мы тоже никого не пощадим.
Re: Типы чисел в DSL
От: Marty Пират https://www.youtube.com/channel/UChp5PpQ6T4-93HbNF-8vSYg
Дата: 02.12.23 00:58
Оценка: 3 (1)
Здравствуйте, Alekzander, Вы писали:

A>Мне нужно спроектировать DSL. С одной стороны, он должен быть строго типизирован (это требование), а с другой — этот тип появится на уровне GUI для массовых пользователей. А их, по возможности, хотелось бы не грузить разницей между int и double (не говоря про потерю точности), а дать им вместо этого некий универсальный тип number. С другой стороны, возможно, стоит один раз научить юзеров разнице между int и double, чем разруливать миллион неоднозначностей.


https://github.com/al-martyn1/marty_decimal


A>Что еще хуже, иногда возможно хранение в переменных сумм денег. Как я знаю, в таких случаях принято использовать третий тип: с эмуляцией вещественности через целые (нужны гарантии, что 0.1 + 0.2 == 0.3). Но три разных типа для чисел — для юзеров это уже будет перебор. Или нет? Может, как раз дать им кучу типов и пусть сами несут ответственность за сходимость балансов? ))


https://github.com/al-martyn1/marty_decimal


A>Сами значения будут храниться в sqlite (он лёгкий, встраиваемый и опенсорсный, но если есть альтернативы, можно рассмотреть). Доступ к ним планируется только через слой этого DSL'я, хотя, конечно же, желательно сохранить возможность обработки (в т.ч. вычислений) через запросы. Я так понимаю, придётся все агрегирующие функции писать самому?


https://github.com/al-martyn1/marty_decimal


A>Итак, что посоветуете для внутреннего представления чисел в памяти и хранения в sqlite? И какими типами это всё оформить для юзеров?


https://github.com/al-martyn1/marty_decimal

Маньяк Робокряк колесит по городу
Re: Типы чисел в DSL
От: vsb Казахстан  
Дата: 02.12.23 01:13
Оценка: 3 (1) -1
Посоветую взять JavaScript и всё. Число это просто double (64-битная плавающая точка).
Отредактировано 02.12.2023 1:13 vsb . Предыдущая версия .
Re[2]: Типы чисел в DSL
От: Alekzander  
Дата: 02.12.23 09:51
Оценка: 40 (1)
Здравствуйте, vsb, Вы писали:

vsb>Посоветую взять JavaScript и всё. Число это просто double (64-битная плавающая точка).


Re: Типы чисел в DSL
От: Pzz Россия https://github.com/alexpevzner
Дата: 02.12.23 10:48
Оценка: 3 (1) +1
Здравствуйте, Alekzander, Вы писали:

A>Мне нужно спроектировать DSL. С одной стороны, он должен быть строго типизирован (это требование), а с другой — этот тип появится на уровне GUI для массовых пользователей. А их, по возможности, хотелось бы не грузить разницей между int и double (не говоря про потерю точности), а дать им вместо этого некий универсальный тип number. С другой стороны, возможно, стоит один раз научить юзеров разнице между int и double, чем разруливать миллион неоднозначностей.


Можно сделать некий универсальный тип int и некий универсальный тип float. Но объединить не получится, у них слишком разные свойства. И эта разница в свойствах, она существенна при выборе типа.

От этого можно отступить, только если все эти тонкости пользователям не важны. Как в JavaScript, например; там все числа — это 64-битный floating point, но известно, что в довольно широком диапазоне целые в нем представляются без потерь точности, поэтому их можно использовать в качестве счетчиков циклов и т.п., особо не задумываясь.

А вот важны эти тонкости пользователям или нет — зависит от самих пользователей и от решаемых ими задач. И это надо как-то с ними обсудить.

A>Что еще хуже, иногда возможно хранение в переменных сумм денег. Как я знаю, в таких случаях принято использовать третий тип: с эмуляцией вещественности через целые (нужны гарантии, что 0.1 + 0.2 == 0.3). Но три разных типа для чисел — для юзеров это уже будет перебор. Или нет? Может, как раз дать им кучу типов и пусть сами несут ответственность за сходимость балансов? ))


Fixed point. Это когда счет идет, например, в сотых. Или в тысячных. Но конкретный выбор фиксируется на уровне типа и не меняется в процессе рассчетов, в отличии от float. Можно объединить с целыми, они — частный случай фиксированной точки.

A>Итак, что посоветуете для внутреннего представления чисел в памяти и хранения в sqlite? И какими типами это всё оформить для юзеров?


Я бы шел от пользовательского интерфейса (который, в данном случае — твоя система типов, видимая пользователям). А когда там устаканится, уже думал бы о деталях реализации.
Re[2]: Типы чисел в DSL
От: Alekzander  
Дата: 02.12.23 11:01
Оценка:
Здравствуйте, IT, Вы писали:

IT>На вскидку я бы ещё тип percent рассмотрел.


Спасибо за напоминание, это хорошая идея. Но я думаю, это сугубо вторичная вещь, которую как тип оформлять вообще не надо. На уровне GUI можно сделать галку "Это проценты". А на уровне DSL... лет двадцать назад мой друг писал эвалюатор математических выражений. Он сделал очень просто: заменял знак % на "/100.0" где это было синтаксически уместно. Можно было написать pi*50% и получить 1.57... Как выяснилось за двадцать лет использования, этот трюк покрывает все юзерские хотелки.

IT>По поводу sqlite, то желательно подробности. Если предполагается минимум данных и нежелательность возни с установками дополнительного софта, то sqlite нормальный выбор.


Так а какие подробности? Все данные имеют характер табличных и хранятся в таблицах. Впрочем, вот две важных подробности. Первая. Нужно, чтобы это собиралось, работало и не тормозило на недорогом телефоне с Android. Тут, я думаю, проблем не будет — в одной компании, где я работал 10 лет назад, sqlite использовали ещё под WinMo на ARM'ах тех времён. Вторая. Нужно много вычислений по формулам (как для каждой строки в вычисляемых колонках, так и для таблицы в целом — min/max/avg/etc). Хранить ли вычисленное и перевычислять из триггеров, или вычислять всё каждый раз на лету — я ещё не решил, мне, так или иначе, понадобится написать eval(), а во втором случае желательно иметь удобный способ его вызова, инициируемый из запроса.
Re[2]: Типы чисел в DSL
От: Alekzander  
Дата: 02.12.23 11:08
Оценка:
Здравствуйте, Marty, Вы писали:

M>https://github.com/al-martyn1/marty_decimal

M>https://github.com/al-martyn1/marty_decimal
M>https://github.com/al-martyn1/marty_decimal
M>https://github.com/al-martyn1/marty_decimal

Я правильно понимаю, что ты посоветовал использовать number, и предложил имплементацию? Если да, можно о ней хотя бы в двух словах рассказать, в частности о том, как сериализовать значения (записывать в sqlite)?
Re[3]: Типы чисел в DSL
От: vsb Казахстан  
Дата: 02.12.23 11:12
Оценка:
Здравствуйте, Alekzander, Вы писали:

vsb>>Посоветую взять JavaScript и всё. Число это просто double (64-битная плавающая точка).


A>Image: firefox_K8XYZyZaEJ.png


Требование про 0.3 не несёт смысла, поэтому я его даже не рассматриваю. Если хочешь обсудить — расскажи подробней, зачем тебе такое требование и какую задачу ты хочешь с его помощью решать. Пока у тебя нет деления, проще всего просто представлять все числа в копейках (или сотых долях копейки, или тебе видней, какая у тебя гранулярность планируется), в double 64 можно засунуть 52-битовое целое число, такого размера хватит для всех разумных целей. Если есть деление — проще с округлением аккуратно работать. Опять же точности double хватит для подавляющего большинства случаев на практике.
Отредактировано 02.12.2023 11:16 vsb . Предыдущая версия . Еще …
Отредактировано 02.12.2023 11:15 vsb . Предыдущая версия .
Re[3]: Типы чисел в DSL
От: Marty Пират https://www.youtube.com/channel/UChp5PpQ6T4-93HbNF-8vSYg
Дата: 02.12.23 12:09
Оценка:
Здравствуйте, Alekzander, Вы писали:

A>Я правильно понимаю, что ты посоветовал использовать number, и предложил имплементацию?


Типа того


A>Если да, можно о ней хотя бы в двух словах рассказать, в частности о том, как сериализовать значения (записывать в sqlite)?


Есть метод std::string toString(int precision) const


Более того, я этот тип писал, чтобы а) хранить деньги без всяких округлений, любые суммы, б) хранить это в базе sqlite
Маньяк Робокряк колесит по городу
Отредактировано 02.12.2023 12:13 Marty . Предыдущая версия .
Re[3]: Типы чисел в DSL
От: Marty Пират https://www.youtube.com/channel/UChp5PpQ6T4-93HbNF-8vSYg
Дата: 02.12.23 12:12
Оценка:
Здравствуйте, Alekzander, Вы писали:

A>Так а какие подробности? Все данные имеют характер табличных и хранятся в таблицах. Впрочем, вот две важных подробности. Первая. Нужно, чтобы это собиралось, работало и не тормозило на недорогом телефоне с Android.


sqlite в андроиде примерно в каждой аппе прикручен. Например, whatsapp хранит базу сообщений в нём
Маньяк Робокряк колесит по городу
Re[4]: Типы чисел в DSL
От: Marty Пират https://www.youtube.com/channel/UChp5PpQ6T4-93HbNF-8vSYg
Дата: 02.12.23 12:18
Оценка: +3
Здравствуйте, vsb, Вы писали:

A>>Image: firefox_K8XYZyZaEJ.png


vsb>Требование про 0.3 не несёт смысла, поэтому я его даже не рассматриваю. Если хочешь обсудить — расскажи подробней, зачем тебе такое требование и какую задачу ты хочешь с его помощью решать. Пока у тебя нет деления, проще всего просто представлять все числа в копейках (или сотых долях копейки, или тебе видней, какая у тебя гранулярность планируется),


А потом захочется другую валюту, с другим количеством условных копеек в условном рубле, и вся эта схема накроется пимедным тзом.


vsb>в double 64 можно засунуть 52-битовое целое число, такого размера хватит для всех разумных целей. Если есть деление — проще с округлением аккуратно работать. Опять же точности double хватит для подавляющего большинства случаев на практике.


В double денег влезает, на самом деле не очень много. Хотя, для домашней бухгалтерии, может и хватит.

Но вообще, хранить деньги в double — очень, очень плохая идея.
Маньяк Робокряк колесит по городу
Re[5]: Типы чисел в DSL
От: vsb Казахстан  
Дата: 02.12.23 13:52
Оценка:
Здравствуйте, Marty, Вы писали:

M>В double денег влезает, на самом деле не очень много. Хотя, для домашней бухгалтерии, может и хватит.


45 триллионов рублей, если считать с копейками. Неплохая у вас домашняя бухгалтерия.
Re[6]: Типы чисел в DSL
От: Marty Пират https://www.youtube.com/channel/UChp5PpQ6T4-93HbNF-8vSYg
Дата: 02.12.23 14:25
Оценка:
Здравствуйте, vsb, Вы писали:

M>>В double денег влезает, на самом деле не очень много. Хотя, для домашней бухгалтерии, может и хватит.


vsb>45 триллионов рублей, если считать с копейками. Неплохая у вас домашняя бухгалтерия.


Попиливал бухгалтерию для торговли на бирже. Прикинул, что вполне могут произойти ситуации, какие-нибудь агрегированные расчеты за года, когда не влезу
Маньяк Робокряк колесит по городу
Re[6]: Типы чисел в DSL
От: Marty Пират https://www.youtube.com/channel/UChp5PpQ6T4-93HbNF-8vSYg
Дата: 02.12.23 14:32
Оценка:
Здравствуйте, vsb, Вы писали:

M>>В double денег влезает, на самом деле не очень много. Хотя, для домашней бухгалтерии, может и хватит.


vsb>45 триллионов рублей, если считать с копейками. Неплохая у вас домашняя бухгалтерия.


Кстати, некоторые акции торгуются по ценам с шестью знаками после точки (в рублях). 640двух знаков под копейки хватит всем, ага
Маньяк Робокряк колесит по городу
Re[7]: Типы чисел в DSL
От: vsb Казахстан  
Дата: 02.12.23 14:33
Оценка:
Здравствуйте, Marty, Вы писали:

M>>>В double денег влезает, на самом деле не очень много. Хотя, для домашней бухгалтерии, может и хватит.


vsb>>45 триллионов рублей, если считать с копейками. Неплохая у вас домашняя бухгалтерия.


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


Очень сомневаюсь, что потеря нижних битов в таких отчётах на что-то повлияет. Типа мы за 33 года имели оборот не 50 123 456 789 111 а 50 123 456 789 121 рублей. Обычно такие числа даже на выводе обрезают, чтобы читать можно было.

Ну и в конце концов для такой специализированной задачи можно и BigInt взять конкретно в этом отчёте.
Re[8]: Типы чисел в DSL
От: Marty Пират https://www.youtube.com/channel/UChp5PpQ6T4-93HbNF-8vSYg
Дата: 02.12.23 14:37
Оценка: +1
Здравствуйте, vsb, Вы писали:

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


vsb>Очень сомневаюсь, что потеря нижних битов в таких отчётах на что-то повлияет. Типа мы за 33 года имели оборот не 50 123 456 789 111 а 50 123 456 789 121 рублей. Обычно такие числа даже на выводе обрезают, чтобы читать можно было.


А я сомневаюсь, что это можно просто проигнорировать


vsb>Ну и в конце концов для такой специализированной задачи можно и BigInt взять конкретно в этом отчёте.


Зачем в разных отчетах использовать разные типы? Если вкорячивать BigInt/BigNumber, почему сразу их везде не использовать и не беспокоится, что где-то что-то в какой-то момент пропадёт?
Маньяк Робокряк колесит по городу
Re[9]: Типы чисел в DSL
От: vsb Казахстан  
Дата: 02.12.23 15:20
Оценка:
Здравствуйте, Marty, Вы писали:

M>Зачем в разных отчетах использовать разные типы? Если вкорячивать BigInt/BigNumber, почему сразу их везде не использовать и не беспокоится, что где-то что-то в какой-то момент пропадёт?


Потому, что double работает очень быстро, а bigint работает очень медленно. Потому, что double поддерживается практически всем софтом, а bigint — далеко не всем, в частности пресловутым sqlite не поддерживается. Делать софт медленней на порядок-два ради мнимых юзкейсов я считаю неправильным.
Re[10]: Типы чисел в DSL
От: Marty Пират https://www.youtube.com/channel/UChp5PpQ6T4-93HbNF-8vSYg
Дата: 02.12.23 15:59
Оценка: +1
Здравствуйте, vsb, Вы писали:

vsb>Потому, что double работает очень быстро, а bigint работает очень медленно.


Очень медленно — это насколько медленно?

У меня очень медленно только деление работает, остальные операции медленно, но уже не очень. +/- работают в 20 раз медленее, умножение — в 50 раз. Это медленно, конечно, но не прям уж так. Если мы не САПР/3D пишем, этим можно пренебречь.

И, в принципе, это ещё можно раза в два ускорить — у меня по байту на десятичный знак, а можно упаковать два знака в байт, это будет побыстрее, но мне лень было, писать несколько посложнее бы было


vsb>Потому, что double поддерживается практически всем софтом, а bigint — далеко не всем,


Что значит — поддерживается?


vsb>в частности пресловутым sqlite не поддерживается.


В частности в пресловутом sqlite внезапно всё хранится строками, а вот всякие обёртки, уже да, любят в дабл конвертить


vsb>Делать софт медленней на порядок-два ради мнимых юзкейсов я считаю неправильным.



Софт не будет медленнее на порядки, потому что операции с этими числами там будут занимать доли процентов от общего времени работы. Никто этого не заметит. А вот гарантии того, что в числе ни один знак не пропадёт и не изменится — в некоторых случаях дорогого стоят. У BigDecimal есть ещё приятная особенность, что можно числа прямо сравнивать, и не приседать с точностью представления.

И ещё по поводу скорости. У меня есть интерфейс рисования, обёртка над GDI и GDI+, и вот там я сделал так, что можно везде использовать double, а можно мой Decimal. Так вот, отрисовка сцены не отличается ни на милисекунды при использовании того или другого, всё равно всё время сжирают вызовы GDI, нужно очень огромные сцены рисовать, с сотнями/тысячами объектов, чтобы тип чисел начал как-то влиять.


А вообще, тех, кто считает деньги в double — их надо сразу расстреливать
Маньяк Робокряк колесит по городу
Re[11]: Типы чисел в DSL
От: vsb Казахстан  
Дата: 02.12.23 16:33
Оценка:
Здравствуйте, Marty, Вы писали:

M>Софт не будет медленнее на порядки, потому что операции с этими числами там будут занимать доли процентов от общего времени работы. Никто этого не заметит. А вот гарантии того, что в числе ни один знак не пропадёт и не изменится — в некоторых случаях дорогого стоят.


Ключевое выделил. Твой пример с биржой и 6 знаками после запятой, вероятно, относится к этим некоторым случаям. 99% остальных юз-кейсов, вероятно, не относятся к этим случаям.

M>У BigDecimal есть ещё приятная особенность, что можно числа прямо сравнивать, и не приседать с точностью представления.


Это пока у тебя деления нет в алгоритмах. Когда появится — там и до рациональных чисел дойти, возможно, придётся. А то и до символьных вычислений.

M>А вообще, тех, кто считает деньги в double — их надо сразу расстреливать


Не убедительно.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.