2011-03-30 93 views
5

我想將可能帶有貨幣符號前綴的十進制值轉換爲數字值。
例如 -
的值可以是像以下任何將帶有貨幣符號的數值轉換回帶有NumberFormat的十進制

String s1 = "£32,847,676.65"; 
String s2 = "£3,456.00"; 
String s3 = "£831,209"; 

我想結果之後轉換到像 - 32847676.653456.00831209
我試圖用這種方式的NumberFormat parse()方法 -

NumberFormat nf = NumberFormat.getCurrencyInstance(Locale.UK); 
numberFormat.setMinimumFractionDigits(2); 
Number num = nf.parse(s1); 
double dd = num.doubleValue(); 
BigDecimal gg = new BigDecimal(dd); 
System.out.println(gg); 

但結果是 - 32847676.649999998509883880615234375這是不太完全正確的。

我需要它是數字,以便可以我可以執行某種計算。
你能指導我與我還有什麼我可以嘗試

回答

5

你已經正確地解析了值。問題是這樣的:

BigDecimal gg = new BigDecimal(dd); 

您covnert價值爲BigDecimal,和雙打的四捨五入問題佔點後的小數位。用途:

BigDecimal gg = new BigDecimal(dd).setScale(2); 

BigDecimal gg = new BigDecimal(dd).setScale(2,RoundingMode.HALF_UP); 
+0

對不起,這是行不通的。如果我sysout'gg.toString()'或'gg.toPlainString()'它會導致'3.3E + 7'和'33000000' – 2011-03-30 10:32:55

+0

@ Swift-Tuttle:對不起,請試試這個變種 – Daniel 2011-03-30 10:37:37

+0

是的,用RoundingMode作品完美。非常感謝。讚賞。 – 2011-03-30 10:47:58

5

當BigDecimal的播放,適當的構造函數是的BigDecimal(字符串VAL)

NumberFormat nf = NumberFormat.getCurrencyInstance(Locale.UK); 
    BigDecimal gg = new BigDecimal(nf.parse(s1).toString()); 
    System.out.println(gg); 

的BigDecimal(double val)將不會構建一個準確十進制表示的double值,這不是您所期望的人類可讀值。有人可能會認爲在Java中編寫新的BigDecimal(0.1)會創建一個等於0.1的BigDecimal(非標度值爲1,標度爲1),但它實際上等於0.1000000000000000055511151231257827021181583404541015625。這是因爲0.1不能完全表示爲雙精度(或者,就此而言,作爲任何有限長度的二元分數)。因此,傳遞給構造函數的值不是正好等於0.1,雖然表面 [...] 因此,通常建議String構造中優先使用這一個」

來源:BigDecimal javadoc

+0

感謝您的解釋。但問題是NumberFormat的'parse()'方法的返回是一個'Number'。因此,如果我能夠根據需要將結果轉換爲「String」,我甚至可以不使用BigDecimal,那在這裏不是問題。 – 2011-03-30 10:39:14

+0

我以前的評論是在你的代碼片段之前。是的,這是行不通的。不過,我想知道是否可以得到'String s2 =「£3,456.00」;'的小數位數。不過謝謝。 – 2011-03-30 10:44:29

+0

我會看看如何在沒有BigDecimal的情況下使用它:) – Tanguy 2011-03-30 10:45:51

0

您可以嘗試以下操作,而不使用BigDecimal或NumberFormat。 ;)

String s1 = "£32,847,676.65"; 
// remove the £ and , 
String s2 = s1.replaceAll("[£,]", ""); 
// then turn into a double 
double d = Double.parseDouble(s2); 
// and round up to two decimal places. 
double value = (long) (d * 100 + 0.5)/100.0; 

System.out.printf("%.2f%n", value); 

打印

32847676.65 

如果youw螞蟻避免你的計算舍入誤差,但不希望重物BIGDECIMAL可以使用long美分。

// value in cents as an integer. 
long value = (long) (d * 100 + 0.5); 

// perform some calculations on value here 

System.out.printf("%.2f%n", value/100.0); 
+0

這是一個非常簡單的解決方案,但我不知道它是一個很好的解決方案。不要讓我工作,我的意思是你知道有時我們使用所謂的骯髒解決方案而不是OO或純粹的編程方法。 – 2011-03-30 11:22:02

+0

許多開發者都有一條規則,只要有錢,就使用BigDecimal。但是,在我所合作的所有銀行中,他們都使用double或int/long。 – 2011-03-30 11:24:22

0

它不能保證工作,但根據NumberFormat的API文檔,其getXyzInstance方法會返回一個DecimalFormat實例「絕大多數語言環境」。這可能可以解釋爲「對於所有語言環境,除非安裝專有語言環境服務提供程序」。

如果你能投你的NumberFormat到DecimalFormat的,你可以告訴它解析爲BigDecimal直接,減少您的代碼:

DecimalFormat nf = (DecimalFormat) NumberFormat.getCurrencyInstance(Locale.UK); 
nf.setParseBigDecimal(true); 
BigDecimal gg = (BigDecimal) nf.parse(s1); 
System.out.println(gg); 

在這種情況下,你將與二進制不準確沒問題浮點數字。

相關問題