What rounding method should you use in Java for mo

2019-07-11 00:22发布

Suppose I have a decimal value in Java that represents money.

What's the best way to round these values?

For example, if I have a value that's calculated based on a tax rate and I end up with a result of, say, 5.3999999999999995 as the tax amount, should I round it to 2 decimal places simply by doing this:

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

to produce the currency value:

5.40

4条回答
再贱就再见
2楼-- · 2019-07-11 00:23

You're already using BigDecimal for the rounding, you're already using a rounding mode that is well-suited for financial applications unless there are specific requirements or regulations that proscribe a different one.

The only thing you absolutely MUST do is take the last step and use BigDecimal to represent the money values throughout your application. That's exactly what it's for, and it's much better suited to that task than double since it can represent decimal fractions exactly as expected.

查看更多
beautiful°
3楼-- · 2019-07-11 00:26

Most applications that calculate money don't use floating point (double, float); they use integer amounts representing a smaller unit. For example in $USD, money can be represented in pennies which is 1/100 of a dollar.

For better accuracy, you may want to have an integer represent 1E-03 ("milli-dollars") or 1E-06. This depends on issues such as interest calculations and your level of precision.

查看更多
一纸荒年 Trace。
4楼-- · 2019-07-11 00:31

Money is usually rounded using the "round half to even" rule (also called "banker's rounding). It says that ties are broken by choosing the closest even digit. This can be shown to eliminate bias in rounding for both positive and negative values. (It's not the only rounding rule that has this property, but it's a nice property to have when dealing with money.)

I don't think that this rule is available in the standard API, although it isn't hard to code it up.

查看更多
兄弟一词,经得起流年.
5楼-- · 2019-07-11 00:44

I agree with @Laurent Pireyn that you should round according to the contract. For example, the IRS has you round to the nearest dollar. They say

You can round off cents to whole dollars on your return. If you do round to whole dollars, you must round all amounts. To round, drop amounts under 50 cents and increase amounts from 50 to 99 cents to the next dollar. For example, $1.39 becomes $1 and $2.50 becomes $3

Nice use of RoundingMode.HALF_EVEN. That eliminates the need for you to write and test an function.

If this actually is a tax rate for the IRS, I think that RoundingMode.HALF_UP would be correct.

查看更多
登录 后发表回答