使用NumberFormat将带有货币符号的数值转换回Decimal

时间:2011-03-30 10:20:56

标签: java

我想将带有货币符号前缀的可能十进制值转换为仅数值 例如 -
该值可以类似于以下任何一种

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并不完全正确。

我需要它是数字,所以我可以进行某种计算 你们可以指导一下我还能尝试什么吗?

4 个答案:

答案 0 :(得分:5)

您已正确解析该值。问题是:

BigDecimal gg = new BigDecimal(dd);

您将值存储到BigDecimal,并且双点的舍入问题占点后面的小数位。使用:

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

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

答案 1 :(得分:5)

使用BigDecimal时,相应的构造函数是 BigDecimal(String 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)会创建一个BigDecimal,它正好等于0.1(未缩放的值为1,比例为1),但是它实际上等于0.1000000000000000055511151231257827021181583404541015625。这是因为0.1不能完全表示为double(或者,就此而言,作为任何有限长度的二进制分数)。因此,传递给构造函数的值并不完全正确等于0.1,尽管有外观。 [...] 因此,通常建议优先使用String构造函数“

来源:BigDecimal javadoc

答案 2 :(得分: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

如果您想在计算中避免舍入错误但不想使用重量级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);

答案 3 :(得分: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);

在这种情况下,您对二进制浮点数的不准确性没有任何问题。