File APIs for Java Developers
Manipulate DOC, XLS, PPT, PDF and many others from your application.
http://aspose.com/file-tools
The moose likes Java in General and the fly likes BigDecimal ROUND_HALF_EVEN rounding mode and the number of digits to the right of the decimal point Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Java » Java in General
Bookmark "BigDecimal ROUND_HALF_EVEN rounding mode and the number of digits to the right of the decimal point " Watch "BigDecimal ROUND_HALF_EVEN rounding mode and the number of digits to the right of the decimal point " New topic
Author

BigDecimal ROUND_HALF_EVEN rounding mode and the number of digits to the right of the decimal point

albert kao
Ranch Hand

Joined: Feb 04, 2010
Posts: 239
My financial application requirement is ROUND_HALF_EVEN rounding mode and the number of digits to the right of the decimal point is 2 in the BigDecimal class.
How to achieve that consistently across multiple java files (Screen1.java, Screen2.java, ...) and reduce the redundant setup code?
Should I use MathContext class?

Test program.
Screen1.java:
[code=java]
BigDecimal number = new BigDecimal("1.01234");
result = number.round(new MathContext(2, RoundingMode.ROUND_HALF_EVEN));
System.out.println("result " + result);

result = number.setScale(2, RoundingMode.ROUND_HALF_EVEN);
System.out.println("result " + result);
Campbell Ritchie
Sheriff

Joined: Oct 13, 2005
Posts: 36514
    
  16
What output are you getting? Have look at this old post. When you go through the API Documentation, look for scale and precision. They mean different things. Also find out what unscaled value means.
What about a utility class to do the rounding?You should also consider whether to validate the input from the screens before it becomes a BigDecimal.
You should read about the round and setScale methods carefully before using them.
albert kao
Ranch Hand

Joined: Feb 04, 2010
Posts: 239
Campbell Ritchie wrote:What output are you getting? Have look at this old post. When you go through the API Documentation, look for scale and precision. They mean different things. Also find out what unscaled value means.
What about a utility class to do the rounding?You should also consider whether to validate the input from the screens before it becomes a BigDecimal.
You should read about the round and setScale methods carefully before using them.


My business requirement is that scale is always 2.
Please review the following code.
Thanks.
dennis deems
Ranch Hand

Joined: Mar 12, 2011
Posts: 808
albert kao wrote:
My business requirement is that scale is always 2.
Please review the following code.
Thanks.


This looks good to me, although BigDecimal is immutable so setting the scale on the parameters doesn't do anything without an assignment. I assume you want v1 = v1.setScale(SCALE) but this violates the principle that parameters passed into a method shouldn't be modified; setting scale without also setting a rounding mode is dangerous because if there is excess value an ArithmeticException is thrown; and technically, even if you know absolutely that there won't be excess value, setting the scale on the operands is unnecessary since you're going to divide anyway. Also, I would prefer to see less ambiguous names given to the parameters, such as "dividend" and "divisor", but that's just me.

Finally, if the scale is always 2 throughout the application, then I would make this value a constant somewhere, and refer to that constant instead of a method local variable.
albert kao
Ranch Hand

Joined: Feb 04, 2010
Posts: 239
Dennis Deems wrote:
albert kao wrote:
My business requirement is that scale is always 2.
Please review the following code.
Thanks.


This looks good to me, although BigDecimal is immutable so setting the scale on the parameters doesn't do anything without an assignment. I assume you want v1 = v1.setScale(SCALE) but this violates the principle that parameters passed into a method shouldn't be modified; setting scale without also setting a rounding mode is dangerous because if there is excess value an ArithmeticException is thrown; and technically, even if you know absolutely that there won't be excess value, setting the scale is unnecessary since you're going to divide anyway. Also, I would prefer to see less ambiguous names given to the parameters, such as "dividend" and "divisor", but that's just me.

Finally, if the scale is always 2 throughout the application, then I would make this value a constant somewhere, and refer to that constant instead of a method local variable.

As per your suggestions, the code is revised as follows:


I should add similar methods for multiply, add, subtract & compareTo, shouldn't I?
Paul Clapham
Bartender

Joined: Oct 14, 2005
Posts: 18141
    
    8

But apart from what Dennis already said, your posted code returns a result which isn't rounded to two decimal places. That wasn't your requirement, was it? (Your requirement isn't all that clear: for example does it apply to intermediate results in complex calculations, or only to the end result?)

Anyway have a look at this code fragment and see what it does:



Note that in line 1, for example, just using "setScale(2)" throws an exception; you have to specify a rounding mode along with the number of decimal places. Note also that the "7" in line 3 is the number of digits and not the number of decimal places. But look especially at the last value output.

albert kao
Ranch Hand

Joined: Feb 04, 2010
Posts: 239
Paul Clapham wrote:But apart from what Dennis already said, your posted code returns a result which isn't rounded to two decimal places. That wasn't your requirement, was it? (Your requirement isn't all that clear: for example does it apply to intermediate results in complex calculations, or only to the end result?)

Anyway have a look at this code fragment and see what it does:



Note that in line 1, for example, just using "setScale(2)" throws an exception; you have to specify a rounding mode along with the number of decimal places. Note also that the "7" in line 3 is the number of digits and not the number of decimal places. But look especially at the last value output.


Please review:




I should add similar methods for multiply, add, subtract & compareTo, shouldn't I?
Winston Gutkowski
Bartender

Joined: Mar 17, 2011
Posts: 7071
    
  16

albert kao wrote:My business requirement is that scale is always 2.

Then I would suggest that precision is irrelevant, and I'd probably do something like:or (maybe even better) simply provide a setToRequiredScale(BigDecimal) method and do something like
BigDecimal result = setToRequiredScale(v1.divide(v2));
That way you can apply it to any calculation or value.

Winston

PS: Another oft-forgotten fact is that BigDecimal is not final, so you could actually extend it to provide a setToRequiredScale() method (or, indeed, apply it to every returned result).


Isn't it funny how there's always time and money enough to do it WRONG?
Artlicles by Winston can be found here
albert kao
Ranch Hand

Joined: Feb 04, 2010
Posts: 239
Winston Gutkowski wrote:
albert kao wrote:My business requirement is that scale is always 2.

Then I would suggest that precision is irrelevant, ....

Scale and precision is independent, so I do not think that precision is irrelevant.
Winston Gutkowski
Bartender

Joined: Mar 17, 2011
Posts: 7071
    
  16

albert kao wrote:
Winston Gutkowski wrote:
albert kao wrote:My business requirement is that scale is always 2.

Then I would suggest that precision is irrelevant, ....

Scale and precision is independent, so I do not think that precision is irrelevant.

But your statement doesn't include any reference to precision, therefore we can't make any assumptions about it; which to me makes it irrelevant for the purposes of this discussion.

Winston
albert kao
Ranch Hand

Joined: Feb 04, 2010
Posts: 239
Winston Gutkowski wrote:
albert kao wrote:
Winston Gutkowski wrote:
albert kao wrote:My business requirement is that scale is always 2.

Then I would suggest that precision is irrelevant, ....

Scale and precision is independent, so I do not think that precision is irrelevant.

But your statement doesn't include any reference to precision, therefore we can't make any assumptions about it; which to me makes it irrelevant for the purposes of this discussion.

Winston


You are right.
My requirement should also include:
The precision is either 15 or 8.
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: BigDecimal ROUND_HALF_EVEN rounding mode and the number of digits to the right of the decimal point
 
Similar Threads
Rounding BigDecimal Calculation Yielded Wrong Result
Reduce scale of BigDecimal to that required to represent exactly?
Converting BigDecimal to long with rounding
a hashkey for double precision numbers
BigDecimal divide question