RoundingMode.HALF_UP中的结果不同

时间:2015-11-24 09:03:03

标签: java

请自由评论我。以下程序出了什么问题。它给出了不同的圆形结果。

public class Test {
    public static String round(double value, int places) {
        BigDecimal bd = new BigDecimal(value);
        bd = bd.setScale(places, RoundingMode.HALF_UP);
        return bd.toPlainString();
    }

    public static void main(String[] args) throws Exception {
        double value1 = 1.1234565;
        System.out.println(round(value1, 6));
        double value2 = 1.1235;
        System.out.println(round(value2, 3));
    }
}

为什么这样出来?

1.123457
1.123   --> Actually, I expect 1.124

在Doc(eclipse)

enter image description here

2 个答案:

答案 0 :(得分:9)

您正在调用BigDecimal(double)构造函数。这记录为:

  

将double转换为BigDecimal,它是double的二进制浮点值的精确十进制表示。返回的BigDecimal的比例是最小值,使得(10scale×val)是一个整数。

这些音符也很有启发性,我建议你阅读它们。

您传入的值恰好是1.12349999999999994315658113919198513031005859375,因为它是最接近的double到1.1235。如果您在致电bd.toPlainString()之前打印setScale,则可以看到。因此,不是在1.123和1.124之间 - 它最接近1.123。

如果您希望BigDecimal值完全 1.1235,我建议您将其作为String传递:

import java.math.*;

public class Test {
    public static String round(String value, int places) {
        BigDecimal bd = new BigDecimal(value);
        bd = bd.setScale(places, RoundingMode.HALF_UP);
        return bd.toPlainString();
    }

    public static void main(String[] args) throws Exception {
        String value1 = "1.1234565";
        System.out.println(round(value1, 6));
        String value2 = "1.1235";
        System.out.println(round(value2, 3));
    }
}

或者您可以使用BigDecimal.valueOf(double)代替new BigDecimal(double) - 但是您仍然遇到了转换真实原始源数据的问题(源代码中的文字)代码)首先进入二进制浮点数,可能会丢失信息。

答案 1 :(得分:1)

问题是您正在使用double的精确表示,包括任何表示错误。一个简单的解决方案是使用double打印时得到的值。

public static String round(double value, int places) {
    return BigDecimal.valueOf(value)
                     .setScale(places, RoundingMode.HALF_UP);
                     .toPlainString();
}

BigDecimal.valueOf使用最简单的值,该值将表示为您拥有的double