BigDecimal и Деньги - PullRequest
       15

BigDecimal и Деньги

7 голосов
/ 01 апреля 2012

Я исследовал и обнаружил, что при работе с валютой лучший способ проводить вычисления - это класс BigDecimal.

Имея это в виду, я работаю над кодом, который конвертирует различные типы иностранной валюты в валюту США и наоборот (в частности, кассовый аппарат, который принимает иностранную валюту и конвертирует ее в деньги США, вычисляет изменение и возврат) эту сумму клиенту в иностранной валюте).

На данный момент многие методы используют double, и два из них принимают int в качестве параметра, который будет использоваться при расчете валюты США.

Вопрос:

Поскольку я хочу использовать класс BigDecimal в своих вычислениях, должен ли я изменить все мои методы, которые выполняют вычисления с использованием double, на BigDecimal?

Ответы [ 2 ]

4 голосов
/ 01 апреля 2012

Да, вы должны изменить все числа с плавающей запятой или двойные, чтобы брать целые, длинные или BigDecimals.

Плавающие и двойные не точны для финансовых расчетов. Очень хорошо использовать шаблон Money для работы с суммами и валютами (это специальный тип Quantity). Для ведения списка денежных средств, возможно, в нескольких валютах, вы фактически делаете MoneyBag, набор Money, который может затем суммировать все значения с заданной целевой валютой и CurrencyExchangeService (курсы обмена валют также должны храниться как BigDecimals).

Округление должно выполняться после каждой операции в соответствии с количеством требуемых десятичных разрядов и алгоритмом округления. Количество знаков после запятой обычно является свойством Currency (см., Например, ISO 4217 ); если не требуется другое число (например, при определении цены на бензин).

Вам определенно следует взглянуть на примеры Фаулера; но я также создал очень простой уни-валютный Money класс для упражнения . Он использует только доллары и округляет до 2 десятичных знаков; но это все еще хорошая основа для будущих расширений.

1 голос
/ 01 апреля 2012

Да, BigDecimal, безусловно, правильный путь (с плавающей точкой почти никогда).Также в JDBC.

Но, сказав это, есть проблема с округлением.В некоторых случаях в европейской программе требуется 6 знаков после запятой.В общем, вы захотите округлить на 2 места на каждом шаге.Если у вас есть количество с двумя десятичными знаками и цена, вы получите 4 десятичных знака и должны округлить.Поэтому, чтобы сделать уродливый интерфейс BigDecimal еще более уродливым, вам, вероятно, понадобятся некоторые вспомогательные функции (multiplyRounded?).

...