请自由评论我。以下程序出了什么问题。它给出了不同的圆形结果。
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)
答案 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
。