Bigdecimal для финансовых расчетов и бесконечных вычислений - PullRequest
4 голосов
/ 01 октября 2011

Я уверен, что на этот вопрос было бы просто ответить, но я не могу на всю жизнь решить, что должно быть сделано.Итак, вот и все: если мы следуем «лучшей практике» использования BigDecimal для финансовых расчетов, как можно обрабатывать вещи (вычисления), которые выдают исключение?

Как в качестве примера: предположим, я должен разделить«пользовательская сумма» для инвестирования в облигации между «n» различными юридическими лицами.Теперь рассмотрим случай, когда пользователь вкладывает 100 долларов США для инвестирования, который будет разделен между 3 облигациями.Эквивалентный код будет выглядеть следующим образом:

public static void main(String[] args) throws Exception {
    BigDecimal bd1 = new BigDecimal("100.0");
    BigDecimal bd2 = new BigDecimal("3");
    System.out.println(bd1.divide(bd2));
}

Но, как мы все знаем, этот конкретный фрагмент кода выдаст ArithmeticException, поскольку деление не заканчивается.Как можно обрабатывать такие сценарии в их коде при использовании типов данных бесконечной точности во время вычислений?

TIA,
sasuke

ОБНОВЛЕНИЕ: Учитывая, что RoundingMode поможет решить эту проблему,Следующий вопрос: почему 100,0 / 3 не 33,33 вместо 33,3?Разве 33,33 не будет «более» точным ответом, поскольку вы ожидаете 33 цента вместо 30?Есть ли способ, которым я могу настроить это?

Ответы [ 3 ]

7 голосов
/ 01 октября 2011

Ответ заключается в использовании одного из методов BigDecimal.divide(), которые задают RoundingMode.

Например, следующее использует режим округления наполовину даже или округление банкиров (но в зависимости от требований более подходит половина или один из других режимов округления) и округляется до 2 десятичных знаков:

bd1.divide(bd2, 2, RoundingMode.HALF_EVEN);
2 голосов
/ 01 октября 2011

divide имеет перегрузку, которая принимает режим округления.Вам нужно выбрать один.Я полагаю, что "половинный" является наиболее часто используемым для денежных расчетов.

1 голос
/ 01 октября 2011
bd1.divide(bd2, 5, BigDecimal.ROUND_FLOOR)

Это пример, в зависимости от желаемого округления.

...