I am using jdk 1.8.0_45, and our tests discovered a bug in rouding. RoundingMode.HALF_DOWN works the same as RoundingMode.HALF_UP when the last decimal that decide the rounding is 5.
I found related issues with RoundingMode.HALF_UP, but they are fixed in update 40. I also put a bug to the oracle, but from my experience they are really unresponsive.
package testjava8;
import java.math.RoundingMode;
import java.text.DecimalFormat;
public class Formatori {
public static void main(String[] args) {
DecimalFormat format = new DecimalFormat("#,##0.0000");
format.setRoundingMode(RoundingMode.HALF_DOWN);
Double toFormat = 10.55555;
System.out.println("Round down");
System.out.println(format.format(toFormat));
format.setRoundingMode(RoundingMode.HALF_UP);
toFormat = 10.55555;
System.out.println("Round up");
System.out.println(format.format(toFormat));
}
}
Actual result: Round down 10.5556 Round up 10.5556
Expected result(obtain with jdk 1.7): Round down 10.5555 Round up 10.5556
Seems that it's intended change. The JDK 1.7 behavior was incorrect.
The problem is that you simply cannot represent the number
10.55555
using thedouble
type. It stores the data in IEEE binary format, so when you assign the decimal10.55555
number to thedouble
variable, you actually get the closest value which can be represented in IEEE format:10.555550000000000210320649784989655017852783203125
. This number is bigger than10.55555
, so it's correctly rounded to10.5556
inHALF_DOWN
mode.You can check some numbers which can be exactly represented in binary. For example,
10.15625
(which is10 + 5/32
, thus1010.00101
in binary). This number is rounded to10.1562
inHALF_DOWN
mode and10.1563
inHALF_UP
mode.If you want to restore the old behavior, you can first convert your number to
BigDecimal
usingBigDecimal.valueOf
constructor, which "translates adouble
into aBigDecimal
, using thedouble
's canonical string representation":