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

Car*_*ohr 4 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
}
Run Code Online (Sandbox Code Playgroud)

我的疑问是,BigDecimal与double和String构造函数有什么不同?

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

BigDecimal valDouble = new BigDecimal("" + 0.35);
Run Code Online (Sandbox Code Playgroud)

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

Sea*_*wen 9

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

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

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


Pet*_*rey 5

你不需要猜测 0.35 代表什么

BigDecimal valDouble = new BigDecimal(0.35);
System.out.println(valDouble);
Run Code Online (Sandbox Code Playgroud)

印刷

0.34999999999999997779553950749686919152736663818359375
Run Code Online (Sandbox Code Playgroud)

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

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

BigDecimal valDouble = BigDecimal.valueOf(0.35);
System.out.println(valDouble);
Run Code Online (Sandbox Code Playgroud)

印刷

0.35
Run Code Online (Sandbox Code Playgroud)

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

double d = 0.35;
double d1 = Math.round(d * 10) / 10.0;
System.out.println(d1);
Run Code Online (Sandbox Code Playgroud)

印刷

0.4
Run Code Online (Sandbox Code Playgroud)