Java BigDecimal bugs with String constructor to rounding with ROUND_HALF_UP

谁说胖子不能爱 提交于 2019-11-26 18:37:17

问题


I'm trying to implement a new grade rounding to BigDecimal class, and I'm getting a possible bug, must probably I doing something wrong. The code below exposes my problem:

public static void main(String[] args) throws IOException {
    BigDecimal valDouble = new BigDecimal(0.35);
    valDouble = valDouble.setScale(1, BigDecimal.ROUND_HALF_UP);
    System.out.println(valDouble.doubleValue()); // prints 0.3

    BigDecimal valString = new BigDecimal(new String("0.35"));
    valString = valString.setScale(1, BigDecimal.ROUND_HALF_UP);
    System.out.println(valString.doubleValue()); // prints 0.4
}

My doubt here is, is BigDecimal different for double and String constructors?

I can't understand this 'bug', at least, I just used a simple string concat to 'solve' it, as below:

BigDecimal valDouble = new BigDecimal("" + 0.35);

Any idea what could be causing this odd behavior?


回答1:


This isn't a bug. 0.35 as a double literal represents a value that is not exactly equal to 0.35; it's likely something like 0.349999995 or something. So it rounds down.

The String constructor lets you specify 0.35 exactly using "0.35", and that rounds up.

Don't use the double constructor here; when it matters enough to use BigDecimal you need to stay out of floating-point land.




回答2:


You don't need to guess what 0.35 is represent as

BigDecimal valDouble = new BigDecimal(0.35);
System.out.println(valDouble);

prints

0.34999999999999997779553950749686919152736663818359375

This will round down to 1 decimal place as 0.3

You don't need to convert to a String, you can use valueOf

BigDecimal valDouble = BigDecimal.valueOf(0.35);
System.out.println(valDouble);

prints

0.35

To round half up to one decimal place you can use

double d = 0.35;
double d1 = Math.round(d * 10) / 10.0;
System.out.println(d1);

prints

0.4



回答3:


0.35 is already inexact, became of the binary radix of FP. Use new BigDecimal("0.35"), which is exact, because of the decimal radix.



来源:https://stackoverflow.com/questions/11368496/java-bigdecimal-bugs-with-string-constructor-to-rounding-with-round-half-up

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!