greatjone

          BlogJava 聯系 聚合 管理
            7 Posts :: 24 Stories :: 3 Comments :: 0 Trackbacks
          Java中的簡單浮點數類型float和double不能夠進行精確運算。
          請看下面實例:
          1public class Test{   
          2    public static void main(String args[]){   
          3        System.out.println(0.05+0.01);   
          4        System.out.println(1.0-0.42);   
          5        System.out.println(4.015*100);   
          6        System.out.println(123.3/100);   
          7    }
             
          8}
            
          9
          其運行結果如下:
          0.060000000000000005
          0.5800000000000001
          401.49999999999994
          1.2329999999999999
          在《Effective Java》這本書中也提到這個原則,float和double只能用來做科學計算或者是工程計算,在商業計算中我們要用java.math.BigDecimal
          我們如果需要精確計算,非要用String來夠造BigDecimal不可!
          下面的這個工具類是是轉載別人的,可以通過個工具類實現小數的精確計算。
           1import java.math.BigDecimal;   
           2/**  
           3* 由于Java的簡單類型不能夠精確的對浮點數進行運算,這個工具類提供精  
           4* 確的浮點數運算,包括加減乘除和四舍五入。  
           5*/
            
           6public class Arith{   
           7    //默認除法運算精度   
           8    private static final int DEF_DIV_SCALE = 10;   
           9    //這個類不能實例化   
          10    private Arith(){   
          11    }
             
          12  
          13    /**  
          14     * 提供精確的加法運算。  
          15     * @param v1 被加數  
          16     * @param v2 加數  
          17     * @return 兩個參數的和  
          18     */
            
          19    public static double add(double v1,double v2){   
          20        BigDecimal b1 = new BigDecimal(Double.toString(v1));   
          21        BigDecimal b2 = new BigDecimal(Double.toString(v2));   
          22        return b1.add(b2).doubleValue();   
          23    }
             
          24    /**  
          25     * 提供精確的減法運算。  
          26     * @param v1 被減數  
          27     * @param v2 減數  
          28     * @return 兩個參數的差  
          29     */
            
          30    public static double sub(double v1,double v2){   
          31        BigDecimal b1 = new BigDecimal(Double.toString(v1));   
          32        BigDecimal b2 = new BigDecimal(Double.toString(v2));   
          33        return b1.subtract(b2).doubleValue();   
          34    }
              
          35    /**  
          36     * 提供精確的乘法運算。  
          37     * @param v1 被乘數  
          38     * @param v2 乘數  
          39     * @return 兩個參數的積  
          40     */
            
          41    public static double mul(double v1,double v2){   
          42        BigDecimal b1 = new BigDecimal(Double.toString(v1));   
          43        BigDecimal b2 = new BigDecimal(Double.toString(v2));   
          44        return b1.multiply(b2).doubleValue();   
          45    }
             
          46  
          47    /**  
          48     * 提供(相對)精確的除法運算,當發生除不盡的情況時,精確到  
          49     * 小數點以后10位,以后的數字四舍五入。  
          50     * @param v1 被除數  
          51     * @param v2 除數  
          52     * @return 兩個參數的商  
          53     */
            
          54    public static double div(double v1,double v2){   
          55        return div(v1,v2,DEF_DIV_SCALE);   
          56    }
             
          57  
          58    /**  
          59     * 提供(相對)精確的除法運算。當發生除不盡的情況時,由scale參數指  
          60     * 定精度,以后的數字四舍五入。  
          61     * @param v1 被除數  
          62     * @param v2 除數  
          63     * @param scale 表示表示需要精確到小數點以后幾位。  
          64     * @return 兩個參數的商  
          65     */
            
          66    public static double div(double v1,double v2,int scale){   
          67        if(scale<0){   
          68            throw new IllegalArgumentException(   
          69                "The scale must be a positive integer or zero");   
          70        }
             
          71        BigDecimal b1 = new BigDecimal(Double.toString(v1));   
          72        BigDecimal b2 = new BigDecimal(Double.toString(v2));   
          73        return b1.divid(b2,scale,BigDecimal.ROUND_HALF_UP).doubleValue();   
          74    }
             
          75  
          76    /**  
          77     * 提供精確的小數位四舍五入處理。  
          78     * @param v 需要四舍五入的數字  
          79     * @param scale 小數點后保留幾位  
          80     * @return 四舍五入后的結果  
          81     */
            
          82    public static double round(double v,int scale){   
          83        if(scale<0){   
          84            throw new IllegalArgumentException(   
          85                "The scale must be a positive integer or zero");   
          86        }
             
          87        BigDecimal b = new BigDecimal(Double.toString(v));   
          88        BigDecimal one = new BigDecimal("1");   
          89        return b.divid(one,scale,BigDecimal.ROUND_HALF_UP).doubleValue();   
          90     }
             
          91  }
            
          92
          posted on 2010-06-06 18:24 jone 閱讀(754) 評論(0)  編輯  收藏 所屬分類: java
          主站蜘蛛池模板: 岑溪市| 合肥市| 金堂县| 桐柏县| 兰溪市| 许昌市| 定州市| 博兴县| 河西区| 丹东市| 庆安县| 永新县| 什邡市| 凤庆县| 襄城县| 鄢陵县| 盱眙县| 哈尔滨市| 黑山县| 鲁山县| 隆化县| 丹寨县| 绵阳市| 珲春市| 武乡县| 盐源县| 安达市| 彰化市| 武穴市| 卢龙县| 新野县| 蓝田县| 肇东市| 东平县| 丹东市| 汾西县| 常山县| 滨海县| 山东省| 汉源县| 赤水市|