zoukankan      html  css  js  c++  java
  • Java中如何解决double和float精度不准的问题

    我们知道浮点数是无法在计算机中准确表示的,例如0.1在计算机中只是表示成了一个近似值,因此,对付点数的运算时结果具有不可预知性。

    在进行数字运算时,如果有double或float类型的浮点数参与计算,偶尔会出现计算不准确的情况。如以下示例代码:

    package ex;
    
    public class BigDeciTest {
        public static void main(String[] args){
            System.out.println(0.05+0.01);
            System.out.println(1.0-0.42);
            System.out.println(4.015*100);
            System.out.println(123.3/100);
            
        }
    
    }

    上述代码执行结果如下:

    0.060000000000000005
    0.5800000000000001
    401.49999999999994
    1.2329999999999999

    在大多数情况下,使用double和float计算的结果是准确的,但是在一些精度要求很高的系统中,这种问题是非常严重的。

    在《Effective Java》中提到一个原则,那就是float和double只能用来作科学计算或者是工程计算,但在商业计算中我们要用java.math.BigDecimal,通过使用BigDecimal类我们可以解决上述问题,实例代码如下:

    package ex;
    
    import java.math.*;
    
    public class BigDecimalDemo {
        public static void main(String[] args){
            System.out.println(ArithUtil.add(0.01, 0.05));
            System.out.println(ArithUtil.sub(1.0, 0.42));
            System.out.println(ArithUtil.mul(4.015, 100));
            System.out.println(ArithUtil.div(123.3, 100));
        }
    }
    
    class ArithUtil{
        private static final int DEF_DIV_SCALE=10;
        
        private ArithUtil(){}
        
        public static double add(double d1,double d2){
            BigDecimal b1=new BigDecimal(Double.toString(d1));
            BigDecimal b2=new BigDecimal(Double.toString(d2));
            return b1.add(b2).doubleValue();
            
        }
        
        public static double sub(double d1,double d2){
            BigDecimal b1=new BigDecimal(Double.toString(d1));
            BigDecimal b2=new BigDecimal(Double.toString(d2));
            return b1.subtract(b2).doubleValue();
            
        }
        
        public static double mul(double d1,double d2){
            BigDecimal b1=new BigDecimal(Double.toString(d1));
            BigDecimal b2=new BigDecimal(Double.toString(d2));
            return b1.multiply(b2).doubleValue();
            
        }
        
        public static double div(double d1,double d2){
    
            return div(d1,d2,DEF_DIV_SCALE);
            
        }
        
        public static double div(double d1,double d2,int scale){
            if(scale<0){
                throw new IllegalArgumentException("The scale must be a positive integer or zero");
            }
            BigDecimal b1=new BigDecimal(Double.toString(d1));
            BigDecimal b2=new BigDecimal(Double.toString(d2));
            return b1.divide(b2,scale,BigDecimal.ROUND_HALF_UP).doubleValue();
            
        }
        
    }

    运行结果如下:

    0.06
    0.58
    401.5
    1.233

    详细,请参考API文档。

    暗夜之中,才见繁星;危机之下,暗藏转机;事在人为,为者常成。
  • 相关阅读:
    Codeforces Round #344 (Div. 2) C. Report 其他
    Codeforces Round #344 (Div. 2) B. Print Check 水题
    Codeforces Round #344 (Div. 2) A. Interview 水题
    8VC Venture Cup 2016
    CDOJ 1280 772002画马尾 每周一题 div1 矩阵快速幂 中二版
    CDOJ 1280 772002画马尾 每周一题 div1 矩阵快速幂
    CDOJ 1279 班委选举 每周一题 div2 暴力
    每周算法讲堂 快速幂
    8VC Venture Cup 2016
    Educational Codeforces Round 9 F. Magic Matrix 最小生成树
  • 原文地址:https://www.cnblogs.com/zenghansen/p/3990311.html
Copyright © 2011-2022 走看看