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

我正在尝试实现一个新的等级舍入到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); 

什么可能导致这种奇怪的行为?

这不是一个错误。 作为双字面值的0.35表示不完全等于0.35的值; 它可能像0.349999995之类的东西。 所以它向下舍入。

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

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

你不需要猜测0.35代表什么

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

版画

 0.34999999999999997779553950749686919152736663818359375 

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

您不需要转换为String,您可以使用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 

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