在項目當中,對于double類型數據的使用比較頻繁。尤其是處理金錢相關的數據,在使用Double類型的數據時,涉及到精度,顯示,四舍五入等等問題。
1. 顯示問題,當double 數據 小于 0.0001 大于等于 10000000時,直接轉為String輸出時,會顯示為科學計數法。
1: double double1 = 0.00009;
2: System.out.println(double1); // 9.0E-5
4: double double2 = 10000000;
5: System.out.println(double2); // 1.0E7
需要使用DecimalFormat 轉化輸出
1: DecimalFormat formate = new DecimalFormat("#.######");
2: System.out.println(formate.format(double1)); //0.00009
3:
4: formate = new DecimalFormat("########.##");
5: System.out.println(formate.format(double2));//10000000
這里面會有四舍五入問題:
1: double double1 = 0.000096789;
2: DecimalFormat formate = new DecimalFormat("#.######");
3: System.out.println(formate.format(double1)); //0.000097
當取小數點后六位時,會在第七位四舍五入。
2. 誤差問題,兩個Double類型的數,進行運算。經常會產生誤差。
1: System.out.println(0.05 + 0.01); //0.060000000000000005
2: System.out.println(1.0 - 0.42); //0.5800000000000001
3: System.out.println(4.015 * 100); //401.49999999999994
4: System.out.println(123.3 / 100); //1.2329999999999999
看似簡單的計算,結果卻出人意料。解決方法是將Double轉為BigDecimal。調用BigDecimal的 運算。
1: double d1 = 0.05;
2: double d2 = 0.01;
3: BigDecimal b1 = new BigDecimal(Double.toString(d1));
4: BigDecimal b2 = new BigDecimal(Double.toString(d2));
5: System.out.println(b1.add(b2)); //0.06
需要注意的是,如果new BigDecimal()時使用的是double類型的構造方法。問題依舊是可能存在的,這邊要使用String參數的構造方法。
3. 兩個double比較的問題。將double數的運算結果和0比較。由于精度問題,比如if(1-0.999999999999999999 == 0.0) 這個是成立的。
附上double數的運算:
1: /**
2: * 兩個Double數相加
3: *
4: * @param v1
5: * @param v2
6: * @return
7: */
8: public static double doubleAdd(Double v1, Double v2) {
9:
10: BigDecimal b1 = new BigDecimal(v1.toString());
11:
12: BigDecimal b2 = new BigDecimal(v2.toString());
13:
14: return b1.add(b2).doubleValue();
15:
16: }
17:
18: /**
19: * 兩個Double數相減
20: *
21: * @param v1
22: * @param v2
23: * @return
24: */
25: public static double doubleSub(Double v1, Double v2) {
26:
27: BigDecimal b1 = new BigDecimal(v1.toString());
28:
29: BigDecimal b2 = new BigDecimal(v2.toString());
30:
31: return b1.subtract(b2).doubleValue();
32:
33: }
34:
35: /**
36: * 兩個Double數相乘
37: *
38: * @param v1
39: * @param v2
40: * @return
41: */
42: public static double doubleMul(Double v1, Double v2) {
43:
44: BigDecimal b1 = new BigDecimal(v1.toString());
45:
46: BigDecimal b2 = new BigDecimal(v2.toString());
47:
48: return b1.multiply(b2).doubleValue();
49:
50: }
51:
52: /**
53: * 兩個Double數相除
54: *
55: * @param v1
56: * @param v2
57: * @return
58: */
59: public static double doubleDiv(Double v1, Double v2) {
60:
61: BigDecimal b1 = new BigDecimal(v1.toString());
62:
63: BigDecimal b2 = new BigDecimal(v2.toString());
64:
65: return b1.divide(b2, DEF_DIV_SCALE, BigDecimal.ROUND_HALF_UP)
66: .doubleValue();
67:
68: }
69:
70: /**
71: * 兩個Double數相除,并保留scale位小數
72: *
73: * @param v1
74: * @param v2
75: * @param scale
76: * @return
77: */
78: public static double doubleDiv(Double v1, Double v2, int scale) {
79:
80: if (scale < 0) {
81:
82: throw new IllegalArgumentException(
83:
84: "The scale must be a positive integer or zero");
85:
86: }
87: int DEF_DIV_SCALE = 10;
88:
89: BigDecimal b1 = new BigDecimal(v1.toString());
90:
91: BigDecimal b2 = new BigDecimal(v2.toString());
92:
93: return b1.divide(b2, scale, BigDecimal.ROUND_HALF_UP).doubleValue();
94:
95: }
posted on 2015-04-22 18:11
藤本薔薇 閱讀(179)
評論(0) 編輯 收藏