2010-03-01 42 views
1

我有一個csv文件,其中的金額和數量字段存在於除首部和尾部的每個記錄明細記錄。預告片記錄具有總計費用值,這是總額詳細記錄中乘以數量字段的總和。我需要檢查拖車總費用值是否等於我的數量和數量字段的計算值。我在所有這些計算中使用雙數據類型關於大十進制

在csv文件中,數量字段顯示爲「10.12」或「10」或「10.0」或「10.456」或「10.4555」或「-10.12」。金額也可以有正值或負值。

在csv文件

H,ABC .....

「d」,..., 「1」, 「12.23」

「d」,... .., 「3」, 「 - 13.334」

「d」,......, 「2」, 「12」

T,CSD,123,12.345

- -------------當Vali我有以下代碼--------------------

   double detChargeCount =0; 

       //From csv file i am reading trailer records charge value 
       String totChargeValue = items[3].replaceAll("\"","").trim(); 

       if (null != totChargeValue && !totChargeValue.equals("")) { 
        detChargeCount = new Double(totChargeValue).doubleValue(); 

       if(detChargeCount==calChargeCount) 
        validflag=true; 

---------------- -------在閱讀CSV文件我有下面的代碼

   if (null != chargeQuan && !chargeQuan.equals("")) { 
         tmpChargeQuan=Long(chargeQuan).longValue(); 
        } 

       if (null != chargeAmount && !chargeAmount.equals("")) { 
         tmpChargeAmt=new Double(chargeAmount).doubleValue(); 
          calChargeCount=calChargeCount+(tmpChargeQuan*tmpChargeAmt); 
          } 

我已經聲明的變量tmpChargeQuan,tmpChargeAmt,calChargeCount爲雙

當我搜索網頁我才知道,雙可能會出現財務計算問題,因此需要使用BIGDECIMAL。但我想知道這種情況適用於我的計算。在我的情況下,小數點後的金額值可以達到5或6位數字「我可以使用雙數據類型進行這種計算嗎?我正在使用它進行驗證。如果我使用上面的代碼使用雙數乘法,會產生問題嗎?

回答

4

我什麼阿迪爾已經succintly回答,您可以適應這些數字爲雙數據類型擴展。問題的問題?當得到計算出的數字,他們將得到正確計算出答案是否定的 - 他們一般不會,如果你考慮與增量不是太大的問題,那就是,你在承擔餘地與否雙價值相當於另一個雙倍價值即但對於涉及確切數字的計算(例如貨幣計算),您必須使用BigDecimal等類型來保存這些值。

當你有這樣的數字: 1.23445 爲double,它可能看起來像1.23445 但它實際上可能是類似 1.234450000003400345543034

當您在數字如,執行多個計算通常這些額外的地方並不重要 - 但是,隨着時間的推移,它們會產生不準確的結果。隨着BigDecimal的,當數被指定爲它的字符串表示,它這個數字 - 它不會遭受「幾乎一樣好」的問題雙打做。

我更新這個答案,包括從BigDecimal的雙重構造的一些注意事項,在這個address找到。

此構造方法的結果可能是 有些不可預測。有人可能會 認爲編寫新 的BigDecimal(0.1)在Java中創建一個 BigDecimal正好等於0.1 (1未測量的值,爲1的比例),但它實際上等於 是 0.1000000000000000055511151231257827021181583404541015625。這是因爲0.1不能 精確表示爲雙(或者, 對於這個問題,作爲一個二進制分數任何有限長度的 )。因此,被在給 構造被傳​​遞的值 不是正好等於 0.1,雖然表面上。

String構造,另外 另一方面,是完全可以預見: 寫入new BigDecimal(「0.1」)將創建一個 BigDecimal正好等於 0.1,正如人們所期望。因此,通常建議 字符串構造函數在 首選項中使用。

當Double必須用作BigDecimal的源 時,請注意這個 構造函數提供了精確的 轉換;它不會給出與使用BigDecimal(String) 構造函數使用 Double.toString(double)方法和 將double轉換爲 字符串的結果相同的 結果。要獲得該結果,請使用 static valueOf(double)方法。

+0

非常感謝 所以你的言論,即使我小數點後有4位數(低精度)。乘法時我可能會遇到錯誤。另外我注意到bigdecimal有一個setscale方法來設置小數點和舍入方法後的數字位數。在我的情況下,我不需要做任何舍入,因爲我只對數值進行驗證。此外,我的輸入可能有時在小數點後有2或3或0個數字。 BigDecimal是否有默認舍入?我將按以下方式分配 BigDecimal aa = new BigDecimal(「11.2359」); – Arav 2010-03-01 04:37:37

+0

除非您已將該數字指定爲double,否則沒有對BigDecimal的默認舍入。你作爲一個字符串輸入的是你得到的。如果您的比例小於當前結果,setScale上的舍入模式肯定是必需的 - 假設您有6.35,並且您說setScale(1) - 根據您選擇的舍入模式,它將使其達到6.3或6.4。 – MetroidFan2002 2010-03-01 14:17:10

+0

非常感謝。所以你說如果我把它放在字符串BigDecimal(「11.2359」)中,並用另一個BigDecimal(「12」)類型進行乘法運算,它將不會結果?如果我把它作爲double BigDecimal(11.2359)給出它,當我進行乘法運算或其他操作時,它會執行什麼樣的默認舍入操作。 如果我想比較兩個大數小數的值來查看它們是否相等,那麼我需要獲得doublevalue,然後檢查它們嗎? – Arav 2010-03-02 01:05:48

2

它不是大小的問題上,它恰好表達浮點數。How the BigDecimal Class Helps Java Get its arithmetic right

+0

感謝很多的鏈接。在BIGDECIMAL中什麼是默認舍入。我不想要發生任何舍入,因爲我在這裏進行驗證。合計每條記錄的數量(數量*金額),最後檢查總費用金額。如果匹配,我會將值添加到表格中。 – Arav 2010-03-01 02:15:58

+0

閱讀文檔不會造成傷害。 :)它會回答你所有關於舍入的問題: http://java.sun.com/j2se/1.5.0/docs/api/java/math/BigDecimal.html – Jay 2010-03-01 02:19:32