如何解决java 浮点型(Double)不准的问题

除了 放弃使用 Double 而使用float 还有什么方法解决Double型不准!?

十进制数的二进制表示可能不够精确浮点数或是双精度浮点数无法精确表示的情况并不少见。浮点数值没办法用十进制来精确表示的原因要归咎于CPU表示浮点数的方法。这样的话您就可能会牺牲一些精度,有些浮点数运算也会引入误差 在有的编程语言中提供了专门的货币类型来处理这种情况,但是Java没有。所以,在商业计算中我们要用:java.math.BigDecimal 。 BigDecimal一共有4个构造方法,其中不属于int的有两个,它们是: 1、BigDecimal(double val) Translates a double into a BigDecimal. 2、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. 所以,如果需要精确计算,非要用String来构造BigDecimal不可。 解决方案: 现在已经可以解决这个问题了,原则是使用BigDecimal并且一定要用String来构造。 但是想像一下吧,如果要做一个加法运算,需要先将两个浮点数转为String,然后构造成BigDecimal,在其中一个上调用add方法,传入另一个作为参数,然后把运算的结果(BigDecimal)再转换为浮点数。没错,这样太繁琐了。 下面的工具类Arith可以简化这部分操作。它提供以下静态方法,包括加减乘除和四舍五入: public static double add(double v1,double v2) public static double sub(double v1,double v2) public static double mul(double v1,double v2) public static double div(double v1,double v2) public static double div(double v1,double v2,int scale) public static double round(double v,int scale) 例import java.math.* ; public class Test2 { public static void main(String args[]) { float v1 = 1f; float v2 = 1.3f; float v3 = v2 - v1; System.out.println("v3 = " + v3 ); //v3 = 0.29999924???? double d1 = 1d; double d2 = 1.3d; double d3 = d2 - d1; System.out.println("d3 = " + d3 ); //d3 = 0.30000000000000004???? BigDecimal bd1 = new BigDecimal("1.0") ; BigDecimal bd2 = new BigDecimal("1.3") ; bd2 = bd2.subtract(bd1); System.out.println(bd2.toString()) ; //0.3 //ROUND_DOWN 是 BigDecimal API 其中一个参数值, 可依需要修改 bd2 = bd2.setScale(2, BigDecimal.ROUND_DOWN); System.out.println(bd2.toString()) ; //0.30 } }
温馨提示:答案为网友推荐,仅供参考
第1个回答  2013-04-16
float的精度更差,应该使用java.math.BigDecimal
第2个回答  2013-04-14
简单明了一句话
用bigdecimal
相似回答