Re[12]: Типы чисел в DSL
От: Marty Пират https://www.youtube.com/channel/UChp5PpQ6T4-93HbNF-8vSYg
Дата: 02.12.23 16:46
Оценка:
Здравствуйте, vsb, Вы писали:

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


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


Мой пример относится к любому финансовому софту. Ну, кроме такого, который написать, запустить, и навсегда забыть. Иначе через 5-10-20 лет это вылезет в виде какой-то внезапной жопы, и что-то сделать уже будет малореально. Это ещё если ты из-за каких-нибудь незамеченных округлений не влетишь на штрафы от фискальных органов


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


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


А в финансах вообще мало делят, там всё больше прибавляют и приумножают Но и в 2D графике у меня мало делений, да и в 3D вроде их не намного больше. И часто, на самом деле, от лишних делений можно просто избавиться, просто оптимизировав алгоритм. Даже если надо на каждом шаге что-то делать, часто такое можно заменить на умножение на обратную величину, которая считается реже. Или просто достаточно один раз в конце разделить, а не на каждом шаге. Но вообще, я пока с проблемами перфоманса по вине своих Decimal не сталкивался, хотя я их много где вместо даблов стал использовать


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


vsb>Не убедительно.


Если будешь писать финансовый софт — скажи нам название, чтобы мы его стороной обходили
Маньяк Робокряк колесит по городу
Re[4]: Типы чисел в DSL
От: Alekzander  
Дата: 02.12.23 21:51
Оценка:
Здравствуйте, vsb, Вы писали:

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


Если ты пишешь калькулятор, ты не знаешь, что с его помощью будут считать юзеры. Твоё дело выдавать результат без сюрпризов. У меня не калькулятор, но суть-то та же.

Вариант просто взять самый большой float из sqlit'овских, назвать его number и отказаться от гарантий точности (т.е. сделать как в JS) — нормальный рабочий вариант, просто хотелось бы сначала понять, что лучше ничего не придумаешь. Вопрос, собственно, и был об этом.
Отредактировано 02.12.2023 22:22 Alekzander . Предыдущая версия .
Re[5]: Типы чисел в DSL
От: Marty Пират https://www.youtube.com/channel/UChp5PpQ6T4-93HbNF-8vSYg
Дата: 02.12.23 22:11
Оценка: +1
Здравствуйте, Alekzander, Вы писали:

A>Вариант просто взять самый большой float из sqlit'овских и назвать его number (т.е. сделать как в JS) — нормальный рабочий вариант, просто хотелось бы сначала понять, что лучше ничего не придумаешь. Вопрос, собственно, и был об этом.


Если именно формат с плавающей точкой — ну, можно и его взять, больше дабла всё равно ничего не будет. Но в SQL есть NUMBER — там и размер, и точность задаётся. Всё финансовое хранится только так.

Для начала надо бы понять, какими проблемами вылезет потом внезапная потеря значащих цифр. Для вещественных чисел в технических вузах дают курс "вычислительная математика"/"численные методы" на семестр-два, в котором разбирают все основные грабли работы с этими числами при численном решении математических задач. Но там потеря значащих цифр допустима. Для бабла ничего лучше BigNumbers нет
Маньяк Робокряк колесит по городу
Re[2]: Типы чисел в DSL
От: Alekzander  
Дата: 02.12.23 22:12
Оценка:
Здравствуйте, Pzz, Вы писали:

Pzz>Я бы шел от пользовательского интерфейса (который, в данном случае — твоя система типов, видимая пользователям). А когда там устаканится, уже думал бы о деталях реализации.


Идеальный GUI — это когда ты выбираешь тип number, а потом вводишь любые дробные и целые числа в пределах диапазона, и они складываются без потери точности. Но ты же сам пишешь, что "не получится". Тогда какой смысл со стороны GUI смотреть, не думая о реализуемости? Мне нужно оптимальное решение, т.е. наилучший GUI, но не вообще, а из тех, что технически реализуемы и не приведут к граблям.

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


Когда ты пишешь тул типа калькулятора, глупо обсуждать с юзерами, что они будут на нём считать, а что нет. Я просто предвижу, что рано или поздно кто-нибудь напишет ==, и это приведёт к проблемам. Кстати, может просто реализовать == через эпсилон, а вывод загрублять на один-два разряда по сравнению с родной точностью double'а того размера, который поддерживается в sqlite'е? Такое будет работать?

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


Я понимаю, что fixed point. Что с ним делать-то? Отдельным типом юзерам дать? Financial number? Или уж сразу объединить с видом валюты, сделать точность два знака после точки, и назвать этот тип currency? Будет number (т.е. double) и currency (т.е. int * 100 + enum валюты).

А нельзя сделать вообще всё (универсальный number) на базе fixed point?

Если что, меня устроит ссылка на какой-нибудь фундаментальный труд "Типы чисел и их представления", если это где-то разжёвано, пойду просвещаться.
Отредактировано 02.12.2023 22:19 Alekzander . Предыдущая версия .
Re: Типы чисел в DSL
От: hi_octane Беларусь  
Дата: 03.12.23 01:51
Оценка: 3 (1) +1
A>Итак, что посоветуете для внутреннего представления чисел в памяти и хранения в sqlite? И какими типами это всё оформить для юзеров?

Если твой DSL заточен на простоту и скорость не принципиальна — я бы создал один тип Number на все применения, на обыкновенных дробях. Как BigRational в Java и C#. Наверняка и для других языков готовые либы есть.

Плюсы — любая точность без округлений, любое число знаков после запятой, возможность хранить на любой платформе одинаковой строкой, не зависящей от железа. Сохранится без потерь везде где есть строки и пройдёт RTT. Возможность честно считать хоть 1/3*3 и получать честную 1, хоть 0.871827897987899987789371982391/2.

Минусы — кушает много байтиков, и работает в разы дольше чем обычная арифметика. Несмотря на минусы, иногда используется даже для числодробильных задач, которые на обычных даблах в разнос уходят.
Re[4]: Типы чисел в DSL
От: Alekzander  
Дата: 03.12.23 10:31
Оценка:
Здравствуйте, Marty, Вы писали:

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


M>Типа того


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


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


M>Более того, я этот тип писал, чтобы а) хранить деньги без всяких округлений, любые суммы, б) хранить это в базе sqlite


А хранишь ты его как? Там есть STRICT Tables, и есть динамика. Первое или второе, и если первое, то какой sqlite'овский тип используешь? (Хотя я обычно за строгую динамическую типизацию, это тот редкий случай, когда я хочу полный контроль и STRICT Tables, т.к. работа с типами — часть моей прикладной задачи).
Re[5]: Типы чисел в DSL
От: Marty Пират https://www.youtube.com/channel/UChp5PpQ6T4-93HbNF-8vSYg
Дата: 03.12.23 11:57
Оценка:
Здравствуйте, Alekzander, Вы писали:

M>>Более того, я этот тип писал, чтобы а) хранить деньги без всяких округлений, любые суммы, б) хранить это в базе sqlite


A>А хранишь ты его как? Там есть STRICT Tables, и есть динамика. Первое или второе, и если первое, то какой sqlite'овский тип используешь? (Хотя я обычно за строгую динамическую типизацию, это тот редкий случай, когда я хочу полный контроль и STRICT Tables, т.к. работа с типами — часть моей прикладной задачи).


Я не помню деталей уже

Вроде бы NUMBER используется

Но что запомнилось, это то, что sqlite хранит всё всегда текстом. Хотя, может это и не так, и я ошибся
Маньяк Робокряк колесит по городу
Re: Типы чисел в DSL
От: Pavel Dvorkin Россия  
Дата: 03.12.23 15:44
Оценка: 3 (1) +1
Здравствуйте, Alekzander, Вы писали:

A>Возник вопрос на стыке проектирования, UX и БД )) Требуются ваши мнения.


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


Ни в коей мере не считая себя специалистом в этом вопросе, выскажу мнение, которое наверняка уязвимо для критики.

Что знает обычный пользователь о данных ? Он знает то, чему его в школе учили. Что числа представляются с некоторой точностью. В десятичной, конечно, системе. Скажем, деньги (в рублях ) — с точностью 2 знака после запятой (копейки). И поэтому если 100 рублей разделить на троих, то каждый получит 33.33 рубля, а лишняя копейка пойдет в счет доходов аглицкого короля. Разделить ее на троих невозможно.

Соответственно, я бы ввел тип Number(I,F) — десятичное число, в котором может быть не более I знаков до запятой и ровно F знаков после.
И вариант его Number(,F) — ограничения на число знаков до запятой не вводится.

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

100.00/3 == 33.33 (школьное деление с точностью до сотых)
100/3 == 3 (школьное деление целых с остатком, который игнорируем)
100.00/6 == 16.67 (школьное с точностью до сотых)
100/6.000 = 16.667 (школьное деление с точностью до тысячных)
100.0/6.000 = 16.667 (школьное деление с точностью до тысячных)
100.00/6.000 = 16.667 (школьное деление с точностью до тысячных)
100.000/6.000 = 16.667 (школьное деление с точностью до тысячных)
100.0000/6.000 = 16.6667 (школьное деление с точностью до десятитысячных)

P.S. Идея заимствована из PL/1. Там был тип DECIMAL FIXED(I,F)
P.P.S Разумеется, округление и контроль переполнения — под капотом, в интерпретаторе DSL.
With best regards
Pavel Dvorkin
Отредактировано 03.12.2023 15:48 Pavel Dvorkin . Предыдущая версия .
Re[2]: Типы чисел в DSL
От: Pauel Беларусь http://blogs.rsdn.org/ikemefula
Дата: 03.12.23 18:42
Оценка:
Здравствуйте, vsb, Вы писали:

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


А если понадобится финансовый инструмент?

Если один тип, то лучше закладываться на long double
Re[3]: Типы чисел в DSL
От: Pauel Беларусь http://blogs.rsdn.org/ikemefula
Дата: 03.12.23 18:45
Оценка:
Здравствуйте, Alekzander, Вы писали:

Pzz>>Я бы шел от пользовательского интерфейса (который, в данном случае — твоя система типов, видимая пользователям). А когда там устаканится, уже думал бы о деталях реализации.


A>Идеальный GUI — это когда ты выбираешь тип number, а потом вводишь любые дробные и целые числа в пределах диапазона, и они складываются без потери точности.


Такого не бывает, к сожалению. Потому нужно представлять юзкейсы, какие вещи могут появиться в ui
Re[3]: Типы чисел в DSL
От: Marty Пират https://www.youtube.com/channel/UChp5PpQ6T4-93HbNF-8vSYg
Дата: 03.12.23 19:21
Оценка: +1
Здравствуйте, Pauel, Вы писали:

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


P>А если понадобится финансовый инструмент?


P>Если один тип, то лучше закладываться на long double


Нет, нет, только не это

#include <iostream>

int main()
{
  std::cout << "sizeof(long double)" << sizeof(long double) << "\n";
  std::cout << "sizeof(double)" << sizeof(double) << "\n";
  return 0;
}


x86-64 clang 13.0.0
sizeof(long double)16
sizeof(double)8


x86-64 gcc 13.2
sizeof(long double)16
sizeof(double)8


MSVC 2005
sizeof(long double)8
sizeof(double)8


MSVC 2017
sizeof(long double)8
sizeof(double)8


BCC 5.5 (да, древнее говно)
sizeof(long double)10
sizeof(double)8


Я когда-то весело попрыгал по граблям, когда прибор выдавал двоичные данные и там был long double, у меня был MSVC, а прошивку прибора писали на бомановском 3.1

Помимо несовместимости разных компиляторов, ты решишь, что 640long double уже точно хватит всем, но это не так, в лучшем случае грабли вылезут чуть попозже, если long double на твоей платформе больше обычного double.

В общем, очень плохая идея. Хуже всех остальных. И таки да, для бабла ничего лучше LongNumber не придумали, а в условном калькуляторе это никак не повлияет на производительность, а от кучи гемора тебя он избавит. Я бы его использовал и не парился
Маньяк Робокряк колесит по городу
Re[4]: Типы чисел в DSL
От: Marty Пират https://www.youtube.com/channel/UChp5PpQ6T4-93HbNF-8vSYg
Дата: 03.12.23 19:27
Оценка: +1
Здравствуйте, Pauel, Вы писали:

A>>Идеальный GUI — это когда ты выбираешь тип number, а потом вводишь любые дробные и целые числа в пределах диапазона, и они складываются без потери точности.


P>Такого не бывает, к сожалению. Потому нужно представлять юзкейсы, какие вещи могут появиться в ui


Почему не бывает? В LongNumber именно так и происходит
Маньяк Робокряк колесит по городу
Re[3]: Типы чисел в DSL
От: Pzz Россия https://github.com/alexpevzner
Дата: 04.12.23 10:23
Оценка:
Здравствуйте, Alekzander, Вы писали:

A>Идеальный GUI — это когда ты выбираешь тип number, а потом вводишь любые дробные и целые числа в пределах диапазона, и они складываются без потери точности. Но ты же сам пишешь, что "не получится". Тогда какой смысл со стороны GUI смотреть, не думая о реализуемости? Мне нужно оптимальное решение, т.е. наилучший GUI, но не вообще, а из тех, что технически реализуемы и не приведут к граблям.


А пользователи, вообще, поймут, что компьютерная арифметика имеет свои ограничения? А то, что ограничения могут быть разными, в зависимости от типа, они поймут?

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


A>Когда ты пишешь тул типа калькулятора, глупо обсуждать с юзерами, что они будут на нём считать, а что нет. Я просто предвижу, что рано или поздно кто-нибудь напишет ==, и это приведёт к проблемам. Кстати, может просто реализовать == через эпсилон, а вывод загрублять на один-два разряда по сравнению с родной точностью double'а того размера, который поддерживается в sqlite'е? Такое будет работать?


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

Может тебе и сделать, как в калькуляторе?

Операция == в калькуляторе, насколько я понимаю, считает равными те числа, которе одинаково на экранчике отображаются.

A>А нельзя сделать вообще всё (универсальный number) на базе fixed point?


Ну, у него точность фиксируется в момент объявления типа. Для одних задач это ОК, для других — не ОК.

A>Если что, меня устроит ссылка на какой-нибудь фундаментальный труд "Типы чисел и их представления", если это где-то разжёвано, пойду просвещаться.


В древних языках было здоровое разнообразие. Теперь всё как-то упростилось
Re: Типы чисел в DSL
От: Sinclair Россия https://github.com/evilguest/
Дата: 04.12.23 10:28
Оценка: 33 (2) +2
Здравствуйте, Alekzander, Вы писали:

A>Возник вопрос на стыке проектирования, UX и БД )) Требуются ваши мнения.


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

Вы забыли самое главное — а что за домен-то, для которого вы проектируете?
Вообще, что int, что double, для нормальных людей являются малопонятной наркоманией, которой нужно избегать как заразы.
Переполнения интов и потери точности для double ведут себя в бытовых сценариях настолько противоестественно, что даже программисты часто ошибаются.

Пункт 1: double не нужен вообще ни для чего, кроме научных расчётов. Если ваша предметная область — не про физику/математику, то забудьте про дабл как про страшный сон.
Пункт 2: так называемые "целые" двоичной разрядности имеют только одно полезное свойство: они быстро обрабатываются компьютером.
Пункт 3: Если в вашей предметной области нет расчётов с триллионами значений, то длинные десятичные будут гораздо более адекватным выбором.
Если есть — то тогда вам пригодятся ограниченные десятичные, которые лишь чуть-чуть медленнее интов, зато ведут себя предсказуемо.

Так что я бы оставил в языке понятие number с известным количеством цифр после запятой (и неограниченным — до запятой).
Если окажется, что такие длинные числа приводят на практике к нехорошестям, то оптимизировал бы язык, заменив в нём представление number на ограниченное.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[13]: Типы чисел в DSL
От: Sinclair Россия https://github.com/evilguest/
Дата: 04.12.23 10:38
Оценка: +2
Здравствуйте, Marty, Вы писали:
M>Мой пример относится к любому финансовому софту. Ну, кроме такого, который написать, запустить, и навсегда забыть. Иначе через 5-10-20 лет это вылезет в виде какой-то внезапной жопы, и что-то сделать уже будет малореально. Это ещё если ты из-за каких-нибудь незамеченных округлений не влетишь на штрафы от фискальных органов
Вылезет не через 5 лет, а немедленно. Те же 0.1 + 0.2 в дабле сложил — и приплызд в неожиданных местах.
Я вообще не понимаю, откуда взялась такая дискуссия в 2023 году. Программисты ещё полсотни лет назад знали, что деньги в даблах хранить нельзя ни в каком случае.

M>А в финансах вообще мало делят, там всё больше прибавляют и приумножают

В том то и дело, что ТС не указал тематику языка. Потому что в финансах обычно операции не такие, как в алгебре. Например, есть операции вроде "есть набор из N чисел, нужно начислить к ним 21.5% налога, и раскидать на N пунктов так, чтобы погрешность в каждой строке и погрешность суммы не превышала 1 младший разряд".

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

Не, мы против смертной казни. Принудительные работы в саппорте до пяти лет. Если группой по предварительному сговору, либо с использованием служебного положения — то от семи до десяти.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[2]: Типы чисел в DSL
От: Marty Пират https://www.youtube.com/channel/UChp5PpQ6T4-93HbNF-8vSYg
Дата: 04.12.23 11:26
Оценка:
Здравствуйте, Sinclair, Вы писали:


S>Так что я бы оставил в языке понятие number с известным количеством цифр после запятой (и неограниченным — до запятой).


У меня в реализации почти так и сделано. Т.е. сложение/вычитание — не меняют числа знаков после запятой, умножение — даёт сумму знаков после запятой множителей (и потом можно округлить, если очень надо), для деления есть static поле precision, до которого производится деление через operator/(). Если надо разделить точнее или грубее — есть специальные методы. Не помню, сделано или нет, но наверно имеет смысл по дефолту делить с точностью precision+1, и затем округлять последний знак дефолтным способом (вот такого статик поля у меня точно сейчас нет, скорее всего Rounding::math используется, если сделано с округлением последнего знака)
Маньяк Робокряк колесит по городу
Re[4]: Типы чисел в DSL
От: Alekzander  
Дата: 04.12.23 18:35
Оценка:
Здравствуйте, Pzz, Вы писали:

A>>Когда ты пишешь тул типа калькулятора, глупо обсуждать с юзерами, что они будут на нём считать, а что нет. Я просто предвижу, что рано или поздно кто-нибудь напишет ==, и это приведёт к проблемам. Кстати, может просто реализовать == через эпсилон, а вывод загрублять на один-два разряда по сравнению с родной точностью double'а того размера, который поддерживается в sqlite'е? Такое будет работать?


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


Pzz>Может тебе и сделать, как в калькуляторе? Операция == в калькуляторе, насколько я понимаю, считает равными те числа, которе одинаково на экранчике отображаются.


Мне как-то не доводилось видеть калькулятор с ==. Я даже не поленился, поднял Жёлтый Мануал от МК-52 (самого продвинутого калькулятора, который знал). И там нет никакого ==, а есть только классика: сравнение с нулём. Что делается проверкой на 0 одного знакового бита и проверкой на 0 всех битов. Поэтому я даже не знаю, "как в калькуляторе" это как где?

A>>А нельзя сделать вообще всё (универсальный number) на базе fixed point?

Pzz>Ну, у него точность фиксируется в момент объявления типа. Для одних задач это ОК, для других — не ОК.

Я понял, спасибо.
Re[2]: Типы чисел в DSL
От: Alekzander  
Дата: 04.12.23 18:56
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>Вы забыли самое главное — а что за домен-то, для которого вы проектируете?


Мы тут недавно по соседству обсуждали Outlook, и, в частности, вот этот диалог:



Какой там домен? Вот и у меня, будем считать, такой же. Домен "Универсальный", как сказали бы маркетологи.

S>Вообще, что int, что double, для нормальных людей являются малопонятной наркоманией, которой нужно избегать как заразы.


Это-то я хорошо понимаю. Но вот столкнувшись с необходимостью как-то имплементировать, я понял, что это не так-то просто.

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


S>Пункт 1: double не нужен вообще ни для чего, кроме научных расчётов. Если ваша предметная область — не про физику/математику, то забудьте про дабл как про страшный сон.

S>Пункт 2: так называемые "целые" двоичной разрядности имеют только одно полезное свойство: они быстро обрабатываются компьютером.
S>Пункт 3: Если в вашей предметной области нет расчётов с триллионами значений, то длинные десятичные будут гораздо более адекватным выбором.
S>Если есть — то тогда вам пригодятся ограниченные десятичные, которые лишь чуть-чуть медленнее интов, зато ведут себя предсказуемо.

S>Так что я бы оставил в языке понятие number с известным количеством цифр после запятой (и неограниченным — до запятой).

S>Если окажется, что такие длинные числа приводят на практике к нехорошестям, то оптимизировал бы язык, заменив в нём представление number на ограниченное.

Понял, принял. Буду думать ))
Отредактировано 04.12.2023 19:26 Alekzander . Предыдущая версия .
Re[4]: Типы чисел в DSL
От: Alekzander  
Дата: 04.12.23 19:22
Оценка:
Здравствуйте, Marty, Вы писали:

M>x86-64 clang 13.0.0

M>x86-64 gcc 13.2
M>MSVC 2005
M>MSVC 2017
M>BCC 5.5 (да, древнее говно)

Ограничивающим фактором является, скорее, вот это: https://www.sqlite.org/datatype3.html

REAL. The value is a floating point value, stored as an 8-byte IEEE floating point number.


Я так понял, другого double у них для нас нет ))

А компиляторы, что ж... Всегда можно обойти эти проблемы через какой-нибудь __тип. Тем более, никто в здравом уме не будет писать в коде long double без тайпдефов из-за этих милых особенностей (если ты об этом).

M>Я когда-то весело попрыгал по граблям, когда прибор выдавал двоичные данные и там был long double, у меня был MSVC, а прошивку прибора писали на бомановском 3.1


M>Помимо несовместимости разных компиляторов, ты решишь, что 640long double уже точно хватит всем, но это не так, в лучшем случае грабли вылезут чуть попозже, если long double на твоей платформе больше обычного double.


M>В общем, очень плохая идея. Хуже всех остальных. И таки да, для бабла ничего лучше LongNumber не придумали, а в условном калькуляторе это никак не повлияет на производительность, а от кучи гемора тебя он избавит. Я бы его использовал и не парился


Послушав всех, я склоняюсь к двум типам: number и currency (название условно).

number как в JS'е (т.е. sqlit'овский 8-байтовый REAL), но с принудительным выводом на разряд меньше (если форматирование не задано) и с эпсилоновской реализацией ==.

currency — sqlit'овский 8-байтовый INTEGER, который fixed point и в сто раз больше + код валюты. "Количество" считаем кодом валюты. (На уровне UI можно их или разделить, или придумать удачное название типа "Currency or quantity" ).

При попытках действий, которые выльются в преобразования, проверять, что currency и currency можно только складывать, вычитать и умножать при совместимом коде (складывать и вычитать строго одинаковые коды, а умножать только валюту на количество или количество на количество). В противном случае — выдавать предупреждение.

Что может пойти не так? (Кроме как всё, само собой).
Отредактировано 04.12.2023 19:23 Alekzander . Предыдущая версия .
Re[5]: Типы чисел в DSL
От: Marty Пират https://www.youtube.com/channel/UChp5PpQ6T4-93HbNF-8vSYg
Дата: 04.12.23 19:46
Оценка:
Здравствуйте, Alekzander, Вы писали:


A>А компиляторы, что ж... Всегда можно обойти эти проблемы через какой-нибудь __тип. Тем более, никто в здравом уме не будет писать в коде long double без тайпдефов из-за этих милых особенностей (если ты об этом).


Или нельзя найти какой-нибудь __тип. Потому что его нет. Найди мне, каким именем 10 байт long double в MSVC называется. А то я хранил его в массиве байт и ручками в double конвертил.


A>currency — sqlit'овский 8-байтовый INTEGER, который fixed point и в сто раз больше + код валюты. "Количество" считаем кодом валюты. (На уровне UI можно их или разделить, или придумать удачное название типа "Currency or quantity" ).


Некоторые акции торгуются по 0.000001 руб за штуку. Не ложится в твой currency. Но можно увеличить размер дробной части, до 6ти знаков, например. Правда, при этом лучше надеяться, что никогда не появится акций с ценой с большим количеством знаков. 0x7FFFFFFFFFFFFFFF/100000 = 92 233 720 368 547 руб. Ну, в принципе, для домашней бухгалтерии хватит. Только не пиши серьёзный софт


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


Для currency это в любом случае неплохо сделать, сделав currency отдельным типом.


A>В противном случае — выдавать предупреждение.


Если пользователю — то да, а так, в коде — только кидать исключение, ибо нефик


A>Что может пойти не так? (Кроме как всё, само собой).


Например, тебе понравится и ты решишь использовать свой fixed point ещё для чего-то. И забудешь, что при умножении надо будет удалять разряды справа. Или, в целом, произведение будет представимо в твоём fixed point, но в процессе умножения до нормализации разрядов произведение таки вылезает за допустимый в int64 диапазон.

Кстати, а дробная часть у тебя как, двоичная или десятичная будет?

В общем, удачки тебе с fixed point
Маньяк Робокряк колесит по городу
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.