我想将带有货币符号前缀的可能十进制值转换为仅数值
例如 -
该值可以类似于以下任何一种
String s1 = "£32,847,676.65";
String s2 = "£3,456.00";
String s3 = "£831,209";
我希望转换后的结果类似于 - 32847676.65
,3456.00
和831209
。
我尝试以这种方式使用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
并不完全正确。
我需要它是数字,所以我可以进行某种计算 你们可以指导一下我还能尝试什么吗?
答案 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构造函数“
答案 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);
在这种情况下,您对二进制浮点数的不准确性没有任何问题。