У нас система, взаимодействующая с другими системами, некоторые из которых даже передают числа в строках, а отдельные экземпляры и хранят их там же (что ж поделаешь с чужими системами?). И когда тестировщик видит в одной системе 2974815.78, а в другой 2974815.75, то начинаются вопросы о том, какую же сумму будет корректно указывать в договоре.
Простите, а можете скинуть ссылки на эти «углы», чтобы ищущие по теме смогли сразу раскрутить клубок, особенно учитывая ограниченность данного материала Явой?
Это не ограниченность явой, это ограниченность модели представления данных с плавающей точкой, описанной в IEEE 754, которая применяется сейчас практически в любом ЯП.
float money problem: About 30,600,000 results (0.38 seconds)
В точных операциях (в том числе и фанансовых) нельзя использовать типы с плавающими точками из-за их ограниченной точности. Даже строка лучше в этой ситуации. В идеале — длинная арифметика. BigDecimal, как я понимаю (java я не знаю) — это оно и есть.
Не сталкивался я на практике с расчётными финансовыми задачами.
В Objective-C для отображения цен использую NSDecimalNumber потому как его для этих целей использует iOS SDK.
Но это таки тип с плавающей точкой, пусть и способен хранить до 38 значимых цифр, и ничего большего чем просто хранение цены с ним делать всё равно не стоит.
Если бы мне пришлось делать какие-то расчётные операции — я бы поискал реализацию длинной арифметики на C и использовал бы её. Из минусов — большое потребление памяти и низкое быстродействие, в сравнении со стандартными типами. Из плюсов — максимальное хранимое значение упирается только в объём доступной оперативной памяти.
Если у нас Java, то никто не мешает сделать класс с полями хранения рублей и копеек отдельными полями long и int, тот же Currency назвать.
А про игры с плавающей точкой уже действительно много написано, на том же хабре куча статей почему это происходит и т.п.
Потеря точности из Double во Float или «Куда пропадали копейки?»