Java BigDecimal使用String构造函数进行错误,以使用ROUND_HALF_UP进行舍入

时间:2012-07-06 19:24:50

标签: java rounding bigdecimal

我正在尝试实现一个新的等级舍入到BigDecimal类,我得到一个可能的错误,我可能做错了。下面的代码暴露了我的问题:

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
}

我的疑问是,对于double和String构造函数,BigDecimal是不同的吗?

我无法理解这个'bug',至少,我只是用一个简单的字符串concat来“解决”它,如下所示:

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

知道可能导致这种奇怪行为的原因是什么?

3 个答案:

答案 0 :(得分:7)

这不是错误。作为双字面值的0.35表示不完全等于0.35的值;它可能像0.349999995之类的东西。所以它结束了。

String构造函数允许您使用“0.35”精确指定0.35,然后向上舍入。

此处不要使用double构造函数;当它足够重要使用BigDecimal时,你需要远离浮点土地。

答案 1 :(得分:3)

您无需猜测0.35代表什么

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

打印

0.34999999999999997779553950749686919152736663818359375

这将向下舍入到小数点后1位为0.3

您无需转换为字符串,可以使用valueOf

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

打印

0.35

要将一半小数舍入到小数点后一位,您可以使用

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

打印

0.4

答案 2 :(得分:0)

0.35已经不精确,成为FP的二进制基数。使用新的BigDecimal(“0.35”),这是精确的,因为十进制基数。