隨筆-71  評(píng)論-5  文章-0  trackbacks-0

          在項(xiàng)目當(dāng)中,對(duì)于double類型數(shù)據(jù)的使用比較頻繁。尤其是處理金錢相關(guān)的數(shù)據(jù),在使用Double類型的數(shù)據(jù)時(shí),涉及到精度,顯示,四舍五入等等問(wèn)題。

          1.  顯示問(wèn)題,當(dāng)double 數(shù)據(jù) 小于 0.0001 大于等于 10000000時(shí),直接轉(zhuǎn)為String輸出時(shí),會(huì)顯示為科學(xué)計(jì)數(shù)法。

             1:  double double1 = 0.00009;
             2:  System.out.println(double1); // 9.0E-5
             3:         
             4:  double double2 = 10000000;
             5:  System.out.println(double2); // 1.0E7

          需要使用DecimalFormat 轉(zhuǎn)化輸出

             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
           
          這里面會(huì)有四舍五入問(wèn)題:
             1:  double double1 = 0.000096789;
             2:  DecimalFormat formate = new DecimalFormat("#.######");
             3:  System.out.println(formate.format(double1)); //0.000097

          當(dāng)取小數(shù)點(diǎn)后六位時(shí),會(huì)在第七位四舍五入。

           

          2. 誤差問(wèn)題,兩個(gè)Double類型的數(shù),進(jìn)行運(yùn)算。經(jīng)常會(huì)產(chǎn)生誤差。

             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

          看似簡(jiǎn)單的計(jì)算,結(jié)果卻出人意料。解決方法是將Double轉(zhuǎn)為BigDecimal。調(diào)用BigDecimal的 運(yùn)算。

             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()時(shí)使用的是double類型的構(gòu)造方法。問(wèn)題依舊是可能存在的,這邊要使用String參數(shù)的構(gòu)造方法。
           
          3. 兩個(gè)double比較的問(wèn)題。將double數(shù)的運(yùn)算結(jié)果和0比較。由于精度問(wèn)題,比如if(1-0.999999999999999999 == 0.0) 這個(gè)是成立的。
           
          附上double數(shù)的運(yùn)算:
             1:      /**
             2:       * 兩個(gè)Double數(shù)相加
             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:       * 兩個(gè)Double數(shù)相減
            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:       * 兩個(gè)Double數(shù)相乘
            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:       * 兩個(gè)Double數(shù)相除
            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:       * 兩個(gè)Double數(shù)相除,并保留scale位小數(shù)
            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 藤本薔薇 閱讀(180) 評(píng)論(0)  編輯  收藏

          只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。


          網(wǎng)站導(dǎo)航:
           
          主站蜘蛛池模板: 卓资县| 光山县| 施秉县| 斗六市| 沙湾县| 金堂县| 霍林郭勒市| 肥城市| 无极县| 登封市| 五峰| 大兴区| 黄浦区| 霞浦县| 合阳县| 古交市| 怀宁县| 庆元县| 安化县| 洞口县| 广安市| 新野县| 太康县| 夏津县| 台州市| 林口县| 新营市| 广东省| 铁力市| 会理县| 博爱县| 石家庄市| 萨嘎县| 杭锦旗| 周至县| 馆陶县| 平度市| 珠海市| 姚安县| 金昌市| 兰西县|