我试图找出几种方法来为double值保留两个小数位。目前,我尝试了以下5种方法。
这5种方法的结果基本一致。但是,在某些情况下,java.math.BigDecimal与其他4种方法的结果不同。
取双倍值 100.0050D ,例如:
使用java.math.BigDecimal时,我的代码中返回100.00。但是其他4种方法返回100.01。结果不一致。
实际上,使用 RoundingMode.HALF_UP 。这是我的问题:
在我的代码中使用java.math.BigDecimal来保留两个带小值的小数位是否有任何遗漏?
或者它是java.math.BigDecimal类中的一个小缺陷?
请帮我解决这个问题。提前谢谢。
此外,我不确定它在各种JDK版本中是否有所不同,只是提供我使用的JDK版本 1.7.0_25 的信息。
代码如下:
public final class PrecisionTest {
private PrecisionTest() {
}
public static String format1(double value) {
BigDecimal bd = new BigDecimal(value);
bd = bd.setScale(2, RoundingMode.HALF_UP);
return bd.toString();
}
public static String format2(double value) {
DecimalFormat df = new DecimalFormat("0.00");
df.setRoundingMode(RoundingMode.HALF_UP);
return df.format(value);
}
public static String format3(double value) {
NumberFormat nf = NumberFormat.getNumberInstance();
nf.setMaximumFractionDigits(2);
nf.setMinimumFractionDigits(2);
nf.setRoundingMode(RoundingMode.HALF_UP);
nf.setGroupingUsed(false);
return nf.format(value);
}
public static String format4(double value) {
return new Formatter().format("%.2f", value).toString();
}
public static String format5(double value) {
return String.format("%.2f", value).toString();
}
}
简单的测试代码如下:
public class Main {
public static void main(String[] args) {
double[] testData = new double[] { 100.123D, 1234567.897D, 100.0050D,
80.0051D,-100245.3658D};
for (double value : testData) {
System.out.println(PrecisionTest.format1(value));
System.out.println(PrecisionTest.format2(value));
System.out.println(PrecisionTest.format3(value));
System.out.println(PrecisionTest.format4(value));
System.out.println(PrecisionTest.format5(value));
}
}
}
答案 0 :(得分:4)
100.005的双重表示并不准确,略低于100.005:
scala> new java.math.BigDecimal(100.0050)
res0: java.math.BigDecimal = 100.0049999999999954525264911353588104248046875
因此,当您设置比例和舍入模式时,它会向下舍入到100.00。
另一方面,使用String构造BigDecimal按预期工作:
scala> new java.math.BigDecimal("100.0050")
res2: java.math.BigDecimal = 100.0050
scala> res2.setScale(2, java.math.RoundingMode.HALF_UP).toString
res3: java.lang.String = 100.01
答案 1 :(得分:2)
double [] testData = new double [] {100.123D,1234567.897D,100.0050D,
80.0051D,-100245.3658D};
问题出在这里。与BigDecimal完全无关。这些数字无法在浮点数中准确表示。尝试从值的 String 表示初始化BigDecimal。