Pull to refresh

Comments 18

Вы храните деньги в double? Зачем?
У нас система, взаимодействующая с другими системами, некоторые из которых даже передают числа в строках, а отдельные экземпляры и хранят их там же (что ж поделаешь с чужими системами?). И когда тестировщик видит в одной системе 2974815.78, а в другой 2974815.75, то начинаются вопросы о том, какую же сумму будет корректно указывать в договоре.
Вот именно. Fixed-point 56.7 использовать надо. Ну а если денег до 16,777,215.99 рублей — то 24.7.
Думаете, лучше хранить в Integer (а кому-то и в Long) в формате <сумма>*100? — Т.е. при выводе и пр. делить на 100, чтобы получить копейки.
Просто удивительно, сколько раз люди попадают на эту проблему.
Хотя мне кажется уже на каждом углу говорят об этом.
UFO just landed and posted this here
«Маловато будет». Пара умножений/делений — и вы вылетите за пределы точности типа даже не заметив.
Простите, а можете скинуть ссылки на эти «углы», чтобы ищущие по теме смогли сразу раскрутить клубок, особенно учитывая ограниченность данного материала Явой?
Это не ограниченность явой, это ограниченность модели представления данных с плавающей точкой, описанной в IEEE 754, которая применяется сейчас практически в любом ЯП.

float money problem: About 30,600,000 results (0.38 seconds)
Я про ограниченность не Явы, а примеров в данном материале, изложенных исключительно на Яве.
Это общепринятый подход. В MS Office, например, даже специальный целочисленный тип данных есть — Currency
В точных операциях (в том числе и фанансовых) нельзя использовать типы с плавающими точками из-за их ограниченной точности. Даже строка лучше в этой ситуации. В идеале — длинная арифметика. BigDecimal, как я понимаю (java я не знаю) — это оно и есть.
В том языке, который Вы предпочитаете, какой тип лучше подходит для хранения денег?
Не сталкивался я на практике с расчётными финансовыми задачами.
В Objective-C для отображения цен использую NSDecimalNumber потому как его для этих целей использует iOS SDK.
Но это таки тип с плавающей точкой, пусть и способен хранить до 38 значимых цифр, и ничего большего чем просто хранение цены с ним делать всё равно не стоит.

Если бы мне пришлось делать какие-то расчётные операции — я бы поискал реализацию длинной арифметики на C и использовал бы её. Из минусов — большое потребление памяти и низкое быстродействие, в сравнении со стандартными типами. Из плюсов — максимальное хранимое значение упирается только в объём доступной оперативной памяти.
BigDecimal bg = new BigDecimal(«2974815.78»);
bg.setScale(2);
System.out.println(bg);

Пара вопросов:
— зачем вам bg.setScale (особой нужды быть не должно...)?
— вы в курсе, что BigDecimal immutable-объект и ваш код — источник проблем?
Верно, исправил.
Если у нас Java, то никто не мешает сделать класс с полями хранения рублей и копеек отдельными полями long и int, тот же Currency назвать.
А про игры с плавающей точкой уже действительно много написано, на том же хабре куча статей почему это происходит и т.п.
Sign up to leave a comment.

Articles