Как стать автором
Обновить

Комментарии 18

Вы храните деньги в double? Зачем?
У нас система, взаимодействующая с другими системами, некоторые из которых даже передают числа в строках, а отдельные экземпляры и хранят их там же (что ж поделаешь с чужими системами?). И когда тестировщик видит в одной системе 2974815.78, а в другой 2974815.75, то начинаются вопросы о том, какую же сумму будет корректно указывать в договоре.
Вот именно. Fixed-point 56.7 использовать надо. Ну а если денег до 16,777,215.99 рублей — то 24.7.
Думаете, лучше хранить в Integer (а кому-то и в Long) в формате <сумма>*100? — Т.е. при выводе и пр. делить на 100, чтобы получить копейки.
В BigDecimal же.
Просто удивительно, сколько раз люди попадают на эту проблему.
Хотя мне кажется уже на каждом углу говорят об этом.
НЛО прилетело и опубликовало эту надпись здесь
«Маловато будет». Пара умножений/делений — и вы вылетите за пределы точности типа даже не заметив.
Простите, а можете скинуть ссылки на эти «углы», чтобы ищущие по теме смогли сразу раскрутить клубок, особенно учитывая ограниченность данного материала Явой?
Это не ограниченность явой, это ограниченность модели представления данных с плавающей точкой, описанной в 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 назвать.
А про игры с плавающей точкой уже действительно много написано, на том же хабре куча статей почему это происходит и т.п.
Зарегистрируйтесь на Хабре , чтобы оставить комментарий

Публикации

Истории