212 похожих чатов

На сколько безопасно хранить денежные единицы в строке?

16 ответов

25 просмотров

храни в int, если центы/копейки актуально, то 1,23 * 100, а при чтении 123 / 100

Michel Angelo
храни в int, если центы/копейки актуально, то 1,...

А в чем смысл такого усложнения? Зачем хранить в int, если можно во float и округлять до сотых результат? Точно такое же округление, как при операциях с копейками. И не надо 2 поля и *100, /100.

Igor
А в чем смысл такого усложнения? Зачем хранить в i...

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

Разве после округления результата возникает вопрос сравнения и интерпретации дробной части? Ну т.е. он возникает, когда не учитывается ожидаемая точность дробной части. Согласен, для операций сравнения float, необходимо использовать обертки, которые учитывают шкалу точности. Но это всё же проще, чем два инта.

Почему два инта? Инт один, по сути ты дробную часть смещаешь в целую до нужной точности

Sergey P
Почему два инта? Инт один, по сути ты дробную част...

Понятно, спасибо. Да, так выглядит проще, если мы заранее можем определить точность дробной части какого-то типа значения. Например, географические координаты - 6 знаков после запятой. Биткойны - 8. Но вот как быть с деньгами? 2 или 4 знака? Сколько я слышал, американская бухгалтерия 4 хочет. Процентные значения зачастую склонны иметь разную точность. А для концепта "количество", какую допустимую точность задавать совсем не понятно, она может варьироваться от случая к случаю. Максимальную не задать, потому что инт закончится.

Igor
Разве после округления результата возникает вопрос...

Практически на любом языке попробуйте написать примерно такой код: if(0.1+0.2 == 0.3) { } Результат вас должен удивить.

RadmirT
Практически на любом языке попробуйте написать при...

В этом примере не присутствует учёт ожидаемой точности при сравнении, о чем я упоминал выше.

Igor
В этом примере не присутствует учёт ожидаемой точн...

Не только точность при сравнении, но и накопления ошибки, если считать много и в вычислениях есть операции * и / то вообще беда. Мне один раз даже пришлось делать вычисления в натуральных дробях чтобы это избежать.

RadmirT
Не только точность при сравнении, но и накопления...

Но на накопление ошибки происходит при округлении, не влияет тип данных, а только факт округления, т.е. ошибка будет накапливаться также при пересчёте и сдвиге инта

RadmirT
Не только точность при сравнении, но и накопления...

И как раз при работе с float и конечным округлением результата вы получите меньше ошибку округления, чем если это округление будет происходить после каждой математической операции, как оно станет с интами для репрезентации флоатов

RadmirT
Практически на любом языке попробуйте написать при...

++ Единственный комментарий, который намекает в сторону Arbitrary-Precision Что является must-have при работе с балансами

Michel Angelo
храни в int, если центы/копейки актуально, то 1,...

Меня в своё время удивило, что 16.9 * 100 !== 1690. Надо не просто умножать, но и всё равно потом округлять

Например в том, что для больших float прибавление сотых не будет иметь эффекта вообще. А для очень больших float прибавление даже единиц не будет иметь эффекта.

Roman K
Например в том, что для больших float прибавление ...

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

Igor
Точно так же как и в случае с решением, когда дроб...

Очень зависит от того, где писать и где хранить

Похожие вопросы

Обсуждают сегодня

а через ESC-код ?
Alexey Kulakov
29
30500 за редактор? )
Владимир
47
Чёт не понял, я ж правильной функцией воспользовался чтобы вывести отладочную информацию? но что-то она не ловится
notme
18
У меня есть функция где происходит это: write_bit(buffer, 1); write_bit(buffer, 0); write_bit(buffer, 1); write_bit(buffer, 1); write_bit(buffer, 1); w...
~
13
Недавно Google Project Zero нашёл багу в SQLite с помощью LLM, о чём достаточно было шумно в определённых интернетах, которые сопровождались рассказами, что скоро всех "ибешни...
Alex Sherbakov
5
program test; {$mode delphi} procedure proc(v: int32); overload; begin end; procedure proc(v: int64); overload; begin end; var x: uint64; begin proc(x); end. Уж не знаю...
notme
6
Как передать управляющий символ в открытую через CreateProcess консоль? Собсна, есть процедура: procedure TRedirectThread.WriteData(Data: OEMString); var Written: Cardinal;...
Serjone
6
вы делали что-то подобное и как? может есть либы готовые? увидел картинку нокода, где всё линиями соединено и стало интересно попробовать то же в ddl на lua сделать. решил с ч...
Victor
8
Ребят в СИ можно реализовать ООП?
Николай
33
Подскажите пожалуйста, как в CustomDrawCell(Sender: TcxCustomGridTableView; ACanvas: TcxCanvas; AViewInfo: TcxGridTableDataCellViewInfo; var ADone: Boolean); получить наз...
A Z
7
Карта сайта