使用java将不同国家的货币转换为双倍
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/23990805/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Converting different countrys currency to double using java
提问by user2649233
I have once scenario where in i get the currencies as a String, for eg:
我曾经有一个场景,我将货币作为字符串获取,例如:
$199.00
199.00 美元
R$ 399,00
399,00 雷亚尔
£25.00
£25.00
90,83
90,83
AED 449.00
449.00 迪拉姆
How do i convert these currencies to double in java?
我如何在 Java 中将这些货币转换为双倍?
采纳答案by Boris the Spider
Never use double
for representing exact amounts
永远不要double
用于表示精确的数量
Well, of course you can do, but you need to really understand floating point arithmetic
嗯,当然可以,但是你需要真正了解浮点运算
Use a NumberFormat
. Whilst it does handle somecurrencies, it's usually easier just to strip all the currency symbols. The NumberFormat
will use Locale
to work out the delimiters to use:
使用一个NumberFormat
. 虽然它确实可以处理一些货币,但通常只去掉所有货币符号更容易。NumberFormat
将用于计算要使用Locale
的分隔符:
public static BigDecimal parse(final String amount, final Locale locale) throws ParseException {
final NumberFormat format = NumberFormat.getNumberInstance(locale);
if (format instanceof DecimalFormat) {
((DecimalFormat) format).setParseBigDecimal(true);
}
return (BigDecimal) format.parse(amount.replaceAll("[^\d.,]",""));
}
This takes a String
of the amount and the Locale
. It then creates a BigDecimal
parsing NumberFormat
instance. It uses replaceAll
and regex to strip all but digits, .
and ,
from the number then parses it.
这需要 aString
的数量和Locale
。然后它创建一个BigDecimal
解析NumberFormat
实例。它使用replaceAll
和正则表达式去除除数字之外的所有内容,.
然后,
从数字中解析它。
A quick demo against your examples:
针对您的示例的快速演示:
public static void main(String[] args) throws ParseException {
final String dollarsA = "9.00";
final String real = "R$ 399,00";
final String dollarsB = "£25.00";
final String tailingEuro = "90,83 ";
final String dollarsC = "9.00";
final String dirham = "AED 449.00";
System.out.println(parse(dollarsA, Locale.US));
System.out.println(parse(real, Locale.FRANCE));
System.out.println(parse(dollarsB, Locale.US));
System.out.println(parse(tailingEuro, Locale.FRANCE));
System.out.println(parse(dollarsC, Locale.US));
System.out.println(parse(dirham, Locale.US));
}
Output:
输出:
199.00
399.00
25.00
90.83
199.00
449.00
I have simply used US
where the decimal is .
and FRANCE
where the decimal is ,
but you could use the correct Locale
for the currency if you wish.
我只是用US
其中小数点是.
与FRANCE
其中小数是,
,但你可以使用正确的Locale
,如果你希望使用的货币。
回答by SteveL
Use contains,replace and valueOf
使用 contains、replace 和 valueOf
if(line.constains("$")){
double value=Double.valueOf(line.replace("$",""));
}
if(line.constains("£")){
double value=Double.valueOf(line.replace("£",""));
}
//same with others
回答by T.J. Crowder
As David Wallace said, you don't (or if you do, you do it verycarefully and only if deeply informed about the issues), because double
is usually not appropriate for use with currency values. It has issues like 0.1 + 0.2
ending up being 0.30000000000000004
(and other such). BigDecimal
used properlyis probably better suited, although dramatically slower. (More on "used properly" below.)
正如大卫华莱士所说,你不这样做(或者如果你这样做,你会非常小心地做,并且只有在深入了解问题的情况下),因为double
通常不适合用于货币价值。它有诸如0.1 + 0.2
最终成为0.30000000000000004
(以及其他类似问题)之类的问题。正确使用可能更适合,尽管速度要慢得多。(更多关于“正确使用”如下。)BigDecimal
First, you have to determine what the thousands and decimal separators being used are, from the locale (see Boris's excellent answer for more on that) or by having that information provided along with the string. In some cultures, they're ,
(thousands) and .
(decimal), e.g. "1,000.24", but in other cultures it's the other way around (e.g., "1.000,24"). For all I know, there are other characters used in some places. (You can't guess this from the string, you have no idea whether "1,234"
means one thousand two hundred and thirty-four or one point two three four.)
首先,您必须确定所使用的千位分隔符和小数分隔符是什么,从语言环境(有关更多信息,请参阅 Boris 的优秀回答)或通过将这些信息与字符串一起提供。在某些文化中,它们是,
(千)和.
(十进制),例如“1,000.24”,但在其他文化中则相反(例如,“1.000,24”)。据我所知,在某些地方还使用了其他字符。(你不能从字符串中猜出这个,你不知道是"1,234"
一千二百三十四还是一点二三四。)
Once you know what they are, you want to remove the thousands separators, convert the decimal to .
(specifically), and then remove all non-digit, non-minus, non-decimals from the string:
一旦你知道它们是什么,你想删除千位分隔符,将小数转换为.
(特别地),然后从字符串中删除所有非数字、非减号、非小数:
// where `currencyString` is the string containing the currency
currencyString = currencyString
.replace(thousandsString, "")
.replace(decimalString, ".")
.replaceAll("[^\d.-]", "");
Then construct your BigDecimal
:
然后构建你的BigDecimal
:
BigDecimal currency = new BigDecimal(currencyString);
...and set the scale and rounding modeappropriate to your program. Also be sure to read the Javadoc carefully for the various operation methods. For instance, as Peter Lawrey pointed out in the comments, a naive use of BigDecimal
will give you runtime exceptions:
...并设置适合您的程序的比例和舍入模式。另外请务必仔细阅读Javadoc,了解各种操作方法。例如,正如 Peter Lawrey 在评论中指出的那样,天真地使用 ofBigDecimal
会给你运行时异常:
BigDecimal bd = new BigDecimal(43);
bd = bd.divide(new BigDecimal(7)); // Throws ArithmeticException
You can deal with those by providing rounding information:
您可以通过提供舍入信息来处理这些问题:
BigDecimal bd = new BigDecimal(43);
bd = bd.divide(new BigDecimal(7), RoundingMode.HALF_UP);
...but again, be sure to set a scale appropriate to what you're doing. For instance, if your scale is only 2
, then (43 / 7) * 7
with RoundingMode.HALF_UP
will be 42.98
instead of 43
. Dividing is particularly tricky, you may need significant scale and then a final rounding back to the more normal currency-level scales (typically 2, but sometimes you may want more places to the right than that).
...但同样,一定要设置一个适合你正在做的事情的比例。例如,如果您的比例仅为2
,则(43 / 7) * 7
withRoundingMode.HALF_UP
将42.98
代替43
。划分特别棘手,您可能需要较大的比例,然后最后四舍五入到更正常的货币级别比例(通常为 2,但有时您可能需要更多的右侧位置)。
If you really, really, really want a double
, use Double.parseDouble
:
如果你真的,真的,真的想要一个double
,使用Double.parseDouble
:
// where `currencyString` is the string containing the currency
currencyString = currencyString
.replace(thousandsString, "")
.replace(decimalString, ".")
.replaceAll("[^\d.-]", "");
double thisWillHaveIssues = Double.parseDouble(currencyString);
回答by Johannes Papo
A simpler way is to use DecimalFormal as in the following example:
更简单的方法是使用 DecimalFormal,如下例所示:
String myMoney = 90,83
String s
try {
s = DecimalFormat.getCurrencyInstance(Locale.getDefault()).parse (myMoney).toString()
} catch (ParseException e) {
return;
}
double d = Double.parseDouble(s);