4

我正在尝试对 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
}

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

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

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

知道是什么导致了这种奇怪的行为吗?

4

3 回答 3

9

这不是错误。0.35 作为双精度字面值表示不完全等于 0.35 的值;它可能是 0.349999995 之类的东西。所以它四舍五入。

String 构造函数允许您使用“0.35”精确地指定 0.35,并且四舍五入。

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

于 2012-07-06T19:28:24.407 回答
5

您无需猜测 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
于 2012-07-06T20:37:16.453 回答
0

0.35 已经不精确了,变成了 FP 的二进制基数。使用 new BigDecimal("0.35"),这是精确的,因为是十进制基数。

于 2012-07-07T02:58:10.287 回答