Какой метод округления следует использовать в Java для получения денег? - PullRequest
2 голосов
/ 06 мая 2011

Предположим, у меня есть десятичное значение в Java, которое представляет деньги.

Какой лучший способ округлить эти значения?

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

double d = 5.3999999999999995
BigDecimal bd = new BigDecimal(d).setScale(2, RoundingMode.HALF_EVEN);
d = bd.doubleValue();

, чтобы получить значение валюты:

5.40

Ответы [ 4 ]

7 голосов
/ 06 мая 2011

Большинство приложений, которые рассчитывают деньги, не используют числа с плавающей запятой (double, float); они используют целые числа, представляющие меньшую единицу. Например, в долларах США деньги могут быть представлены в пенни , что составляет 1/100 доллара.

Для большей точности вам может понадобиться целое число, представляющее 1E-03 («миллидоллары») или 1E-06. Это зависит от таких вопросов, как расчет процентов и ваш уровень точности.

3 голосов
/ 06 мая 2011

Я согласен с @Laurent Pireyn, что вы должны округлять в соответствии с контрактом. Например, у IRS есть округление до ближайшего доллара. Они говорят

Вы можете округлить центы до целого долларов на ваше возвращение. Если вы делаете округлить до целых долларов, вы должны округлить все суммы. Чтобы округлить, сбрасывать суммы до 50 центов и увеличение суммы от 50 до 99 центов до следующего доллар. Например, $ 1,39 становится $ 1 и $ 2,50 становится $ 3

Хорошее использование RoundingMode.HALF_EVEN. Это избавляет вас от необходимости писать и тестировать функцию.

Если это фактически налоговая ставка для IRS, я думаю, что RoundingMode.HALF_UP будет правильным.

1 голос
/ 06 мая 2011

Вы уже используете BigDecimal для округления, вы уже используете режим округления, который хорошо подходит для финансовых приложений, если нет особых требований или правил, предписывающих другое.

Единственное, что вы абсолютно ДОЛЖНЫ сделать, это сделать последний шаг и использовать BigDecimal для представления денежных значений в вашем приложении.Это именно то, для чего он предназначен, и он гораздо лучше подходит для этой задачи, чем double, поскольку он может представлять десятичные дроби точно так, как ожидается.

1 голос
/ 06 мая 2011

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

Я не думаю, что это правило доступнов стандартном API, хотя его нетрудно закодировать.

...