Win a copy of Rust Web Development this week in the Other Languages forum!
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Tim Cooke
  • Campbell Ritchie
  • Ron McLeod
  • Liutauras Vilda
  • Jeanne Boyarsky
Sheriffs:
  • Junilu Lacar
  • Rob Spoor
  • Paul Clapham
Saloon Keepers:
  • Tim Holloway
  • Tim Moores
  • Jesse Silverman
  • Stephan van Hulst
  • Carey Brown
Bartenders:
  • Al Hobbs
  • Piet Souris
  • Frits Walraven

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

 
Ranch Hand
Posts: 260
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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);
 
Marshal
Posts: 74627
335
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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
Posts: 260
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

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.
 
Ranch Hand
Posts: 808
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

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
Posts: 260
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

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?
 
Sheriff
Posts: 26947
83
Eclipse IDE Firefox Browser MySQL Database
  • Likes 2
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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
Posts: 260
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

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?
 
Bartender
Posts: 10780
71
Hibernate Eclipse IDE Ubuntu
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

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).
 
albert kao
Ranch Hand
Posts: 260
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

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
Posts: 10780
71
Hibernate Eclipse IDE Ubuntu
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

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
Posts: 260
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

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.
 
With a little knowledge, a cast iron skillet is non-stick and lasts a lifetime.
reply
    Bookmark Topic Watch Topic
  • New Topic