在JAVA中double ,float有时候不能精确计算,例如:
import java.math.BigDecimal; import java.text.DecimalFormat; import java.text.NumberFormat;
public class NumberFormatTest {
public static void main(String[] args){
double a=0.05;
double b=0.01;
System.out.println(a+b);
System.out.println(add(a,b));
System.out.println(add1(a,b)); }
private static double add1(double a, double b) {
BigDecimal aa=new BigDecimal(String.valueOf(a));
BigDecimal bb=new BigDecimal(String.valueOf(b));
return aa.add(bb).doubleValue(); }
private static double add(double a, double b) {
BigDecimal aa=new BigDecimal(a);
BigDecimal bb=new BigDecimal(b);
return aa.add(bb).doubleValue();
}
}
运行上述程序得到的结果是:
0.060000000000000005
0.060000000000000005
0.06
直接进行double运算得不到精确的结果,而直接转为BigDecimal类同样没得到准确结果,
在将double先转化为String时,才可以。
下面是转载牛人的分析:
BigDecimal(double val)
Translates a double into a BigDecimal.
BigDecimal(String val)
Translates the String repre sentation of a BigDecimal into a BigDecimal.
上面的API简要描述相当的明确,而且通常情况下,上面的那一个使用起来要方便一些。我们可能想都不想就用上了,会有什么问题呢?等到出了问题的时候,才发现上面哪个够造方法的详细说明中有这么一段:
Note: the results of this constructor can be somewhat unpredictable. One might assume that new BigDecimal(.1) is exactly equal to .1, but it is actually equal to .1000000000000000055511151231257827021181583404541015625. This is so because .1 cannot be represented exactly as a double (or, for that matter, as a binary fraction of any finite length). Thus, the long value that is being passed in to the constructor is not exactly equal to .1, appearances nonwithstanding.
The (String) constructor, on the other hand, is perfectly predictable: new BigDecimal(".1") is exactly equal to .1, as one would expect. Therefore, it is generally recommended that the (String) constructor be used in preference to this one.
结论:用double直接计算时,首先将double转换为String,然后转为BigDecimal类,进行运算,这样会避免结果不准确。