Rounding mode with BigDecimal in Java

31,421

The behavior is well described in the Javadoc:

Rounding mode to round towards the "nearest neighbor" unless both neighbors are equidistant, in which case, round towards the even neighbor.

So given the number 4.5, which falls right in the middle of the range of numbers between 4 and 5, when you call:

BigDecimal value1 = new BigDecimal("4.5").setScale(RoundingMode.ROUND_HALF_EVEN);

The runtime needs to figure out which neighbor to round too, aka, should it round to 4, or to 5? Normally it would round based on which value 4.5 is closer to, but in this case its close to both neighbors. Instead of arbitrarily picking the final result though, it picks the even number. This is the behavior of ROUND_HALF_EVEN. If you wanted to, you could specify ROUND_HALF_UP and the final result would have been 5, and not 4. Also, keep in mind that the determination about how to round is based on what the final result would be (and not on the decimal portion of the big decimal, as you seem to have assumed).

Share:
31,421
Tiny
Author by

Tiny

Just an orphan kid and have no more to say. Three things in general, cannot be avoided (at least I can never) Mother Mother-tongue Mother-land. They are always unique. I'm a family-less boy. My family was hunted leaving me all alone when my house targeted and deliberately set on a fire by a mob during a nonsense communal riot but I was survived by a rescue team with the help of firemen. As a survival, I didn't know whether it was my fortune or misfortune but when I recovered, the rescue team came to my home, one day. One of the members gave me a piece of paper in my hand in which the following text was written. lifeisnowhere. He asked me to read it carefully and I could hardly interpret the text as Life is now here, instead of Life is nowhere. All of them gave me a cute smile and went away and I decided to live peacefully and hopefully on their saying from then onwards and very soon. Because of this tragedy, I'm alone couldn't join a school but a curiosity to learn something made me a self-learner. I'm indeed a self-learner, so I'm likely not able to answer any questions on this site right now. In the field of computer science, my self-study mainly includes, QBASIC, C, C++, C#, VB, Java, JavaScript, PHP and a little about ASP.NET. Oracle, MySQL and MSSQL-Server with DBMS. and other theoretical subjects. I'm currently dealing with - Android and Java EE including Servlet, JSP-JSTL/EL (with Spring and Struts with ORM models JPA/Hibernate) and JSF.

Updated on March 12, 2020

Comments

  • Tiny
    Tiny about 4 years

    The following code which uses RoundingMode.HALF_EVEN,

    BigDecimal value1 = new BigDecimal("4.5");
    value1=value1.setScale(0, RoundingMode.HALF_EVEN);
    
    BigDecimal value2 = new BigDecimal("6.5");
    value2=value2.setScale(0, RoundingMode.HALF_EVEN);
    
    System.out.println(value1+"\n"+value2);
    

    displays 4 and 6 respectively. It seems to me that it should display 5 and 7 respectively because the digit to the left of the discarded fractional part (which is 5 in this case) is odd. In this case, it performs RoundingMode.HALF_UP

    And in case of RoundingMode.HALF_UP, RoundingMode.UP is performed when the discarded fractional part is >=0.5 (which is true), otherwise RoundingMode.DOWN is performed.

  • Tiny
    Tiny about 11 years
    I didn't get this quoted text.
  • Perception
    Perception about 11 years
    @Tiny, it means that if the number you are rounding, in half even mode, falls in the center of the range between an odd and even number, that the even number will be the result of the rounding operation.
  • Tiny
    Tiny about 11 years
    If you can, please explain with a simple example. I find this very basic thing difficult to understand and personally, I cannot consult someone to help.
  • Perception
    Perception about 11 years
    Added some detail to my answer, hope that helps
  • sanluck
    sanluck almost 8 years
    I'm using Java 8. There are no method setScale(RoundingMode roundingMode) in BigDecimal, the closest method is setScale(int newScale, RoundingMode roundingMode) and there are no variable RoundingMode.ROUND_HALF_EVEN. I suppose that variables changed.