2011-03-30 38 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); 

在这种情况下,你将与二进制不准确没问题浮点数字。

相关问题