Я думал, что java.math.BigDecimal должен быть "Ответ & торговля"; к необходимости выполнения бесконечной точности арифметики с десятичными числами.
Рассмотрим следующий фрагмент:
import java.math.BigDecimal;
//...
final BigDecimal one = BigDecimal.ONE;
final BigDecimal three = BigDecimal.valueOf(3);
final BigDecimal third = one.divide(three);
assert third.multiply(three).equals(one); // this should pass, right?
Я ожидаю, что assert пройдет, но на самом деле выполнение даже не доходит: one.divide(three) вызывает выброс ArithmeticException!
Exception in thread "main" java.lang.ArithmeticException:
Non-terminating decimal expansion; no exact representable decimal result.
at java.math.BigDecimal.divide
Оказывается, это поведение явно задокументировано в API:
В случае
divideточное частное может иметь бесконечно длинное десятичное разложение; например, 1 делится на 3. Если фактор имеет неограничивающее десятичное расширение, и операция указана для возврата точного результата, генерируетсяArithmeticException. В противном случае возвращается точный результат деления, как это сделано для других операций.
Далее, просматривая API, обнаруживается, что на самом деле существуют различные перегрузки divide, которые выполняют неточное деление, то есть:
final BigDecimal third = one.divide(three, 33, RoundingMode.DOWN);
System.out.println(three.multiply(third));
// prints "0.999999999999999999999999999999999"
Конечно, теперь очевидный вопрос: "Какая точка???". Я думал, что BigDecimal является решением, когда нам нужна точная арифметика, например. для финансовых расчетов. Если мы точно не можем даже divide, то насколько это полезно? Действительно ли это служит общей цели, или это полезно только в очень нишевом приложении, где вам, к счастью, просто не нужно divide вообще?
Если это не правильный ответ, что мы можем использовать для точного деления в финансовых расчетах? (Я имею в виду, у меня нет финансового специалиста, но они все еще используют деление, правильно?).