java. math. How does roundingmode work?

I'm having trouble rounding Specifically, after reading all the JavaDocs, I look forward to the following code:

int n = (integer between 0 and 9,included)
new BigDecimal(n + 0.555d).setScale(2,RoundingMode.HALF_UP).doubleValue()

Returns n 0.56 Instead, these are the return values of N from 0 to 4:

new BigDecimal(0.555d).setScale(2,RoundingMode.HALF_UP).doubleValue()
 0.56
 new BigDecimal(1.555d).setScale(2,RoundingMode.HALF_UP).doubleValue()
 1.55
 new BigDecimal(2.555d).setScale(2,RoundingMode.HALF_UP).doubleValue()
 2.56
 new BigDecimal(3.555d).setScale(2,RoundingMode.HALF_UP).doubleValue()
 3.56
 new BigDecimal(4.555d).setScale(2,RoundingMode.HALF_UP).doubleValue()
 4.55

I also try to change the rounding mode:

int n = (integer between 0 and 9,RoundingMode.HALF_DOWN).doubleValue()

The result of each n is expected to be n 0.55 Instead, the return value is exactly the same as the previous example:

new BigDecimal(0.555d).setScale(2,RoundingMode.HALF_DOWN).doubleValue()
 0.56
 new BigDecimal(1.555d).setScale(2,RoundingMode.HALF_DOWN).doubleValue()
 1.55
 new BigDecimal(2.555d).setScale(2,RoundingMode.HALF_DOWN).doubleValue()
 2.56
 new BigDecimal(3.555d).setScale(2,RoundingMode.HALF_DOWN).doubleValue()
 3.56
 new BigDecimal(4.555d).setScale(2,RoundingMode.HALF_DOWN).doubleValue()
 4.55

Did I miss anything?

Solution

The problem you encounter is that double is not an exact representation. You are round based on this imprecise number

BigDecimal bd = new BigDecimal(1.555d);
System.out.println("bd=" + bd);
bd = bd.setScale(2,RoundingMode.HALF_UP);
System.out.println("after rounding bd=" + bd);
double d = bd.doubleValue();
System.out.println("after rounding d=" + d);

print

bd=1.5549999999999999378275106209912337362766265869140625
after rounding bd=1.55
after rounding d=1.55

however

BigDecimal bd = BigDecimal.valueOf(1.555d);
System.out.println("bd=" + bd);
bd = bd.setScale(2,RoundingMode.HALF_UP);
System.out.println("after rounding bd=" + bd);
double d = bd.doubleValue();
System.out.println("after rounding d=" + d);

print

bd=1.555
after rounding bd=1.56
after rounding d=1.56

This is valid because BigDecimal Valueof makes some additional rounding based on the double that appears when printing

However, I won't use BigDecimal unless performance / simplicity is not a problem

double d = 1.555d;
System.out.println("d=" + d);
d = roundToTwoPlaces(d);
System.out.println("after rounding d=" + d);

public static double roundToTwoPlaces(double d) {
    return ((long) (d < 0 ? d * 100 - 0.5 : d * 100 + 0.5)) / 100.0;
}

print

d=1.555
after rounding d=1.56

For more details, double your money again compares the performance of different rounding methods

The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>