쉼표를 소수 구분 기호로 사용하여 이중을 구문 분석하는 가장 좋은 방법입니다.
콤마가 소수 구분자로 사용되기 때문에 이 코드는 다음과 같이 느려집니다.
String p="1,234";
Double d=Double.valueOf(p);
System.out.println(d);
더 나은 해석 방법은 없을까?"1,234"
갖기 위해1.234
그 이상:p = p.replaceAll(",",".");
?
NumberFormat format = NumberFormat.getInstance(Locale.FRANCE);
Number number = format.parse("1,234");
double d = number.doubleValue();
갱신일 :
다국어 앱을 지원하려면 다음을 사용하십시오.
NumberFormat format = NumberFormat.getInstance(Locale.getDefault());
이것을 사용할 수 있습니다(프랑스 로케일은,
소수 구분 기호)
NumberFormat nf = NumberFormat.getInstance(Locale.FRANCE);
nf.parse(p);
또는 다음과 같은 적절한 기호를 사용하여 설정할 수 있습니다.
DecimalFormat df = new DecimalFormat();
DecimalFormatSymbols symbols = new DecimalFormatSymbols();
symbols.setDecimalSeparator(',');
symbols.setGroupingSeparator(' ');
df.setDecimalFormatSymbols(symbols);
df.parse(p);
E-Riz가 지적한 바와 같이 번호format.parse(String)는 "1,23abc"를 1.23으로 해석합니다.전체 입력 정보를 얻으려면 다음을 사용하십시오.
public double parseDecimal(String input) throws ParseException{
NumberFormat numberFormat = NumberFormat.getNumberInstance(Locale.getDefault());
ParsePosition parsePosition = new ParsePosition(0);
Number number = numberFormat.parse(input, parsePosition);
if(parsePosition.getIndex() != input.length()){
throw new ParseException("Invalid input", parsePosition.getIndex());
}
return number.doubleValue();
}
Double.parseDouble(p.replace(',','.'))
...는 기본 문자 배열을 문자 단위로 검색하기 때문에 매우 빠릅니다.문자열 치환 버전은 평가할 RegEx를 컴파일합니다.
기본적으로 치환(char, char)이 약 10배 빠릅니다.이러한 작업은 로우레벨 코드로 진행되기 때문에 이 점에 대해 생각해 볼 필요가 있습니다.핫스팟 옵티마이저는 알아내지 못할 거야확실히 내 체질에는 없어.
올바른 로케일을 알 수 없고 문자열에 천 개의 구분 기호를 사용할 수 있는 경우, 이것이 마지막 수단이 될 수 있습니다.
doubleStrIn = doubleStrIn.replaceAll("[^\\d,\\.]++", "");
if (doubleStrIn.matches(".+\\.\\d+,\\d+$"))
return Double.parseDouble(doubleStrIn.replaceAll("\\.", "").replaceAll(",", "."));
if (doubleStrIn.matches(".+,\\d+\\.\\d+$"))
return Double.parseDouble(doubleStrIn.replaceAll(",", ""));
return Double.parseDouble(doubleStrIn.replaceAll(",", "."));
주의: 이렇게 하면 "R 1 52.43,2" ~ "15243"과 같은 문자열이 해석됩니다.2".
내 코드에서 사용하는 정적 메서드는 다음과 같습니다.
public static double sGetDecimalStringAnyLocaleAsDouble (String value) {
if (value == null) {
Log.e("CORE", "Null value!");
return 0.0;
}
Locale theLocale = Locale.getDefault();
NumberFormat numberFormat = DecimalFormat.getInstance(theLocale);
Number theNumber;
try {
theNumber = numberFormat.parse(value);
return theNumber.doubleValue();
} catch (ParseException e) {
// The string value might be either 99.99 or 99,99, depending on Locale.
// We can deal with this safely, by forcing to be a point for the decimal separator, and then using Double.valueOf ...
//http://stackoverflow.com/questions/4323599/best-way-to-parsedouble-with-comma-as-decimal-separator
String valueWithDot = value.replaceAll(",",".");
try {
return Double.valueOf(valueWithDot);
} catch (NumberFormatException e2) {
// This happens if we're trying (say) to parse a string that isn't a number, as though it were a number!
// If this happens, it should only be due to application logic problems.
// In this case, the safest thing to do is return 0, having first fired-off a log warning.
Log.w("CORE", "Warning: Value is not a number" + value);
return 0.0;
}
}
}
Kotlin에서는 다음과 같이 내선번호를 사용할 수 있습니다.
fun String.toDoubleEx() : Double {
val decimalSymbol = DecimalFormatSymbols.getInstance().decimalSeparator
return if (decimalSymbol == ',') {
this.replace(decimalSymbol, '.').toDouble()
} else {
this.toDouble()
}
}
코드의 모든 장소에서 다음과 같이 사용할 수 있습니다.
val myNumber1 = "5,2"
val myNumber2 = "6.7"
val myNum1 = myNumber1.toDoubleEx()
val myNum2 = myNumber2.toDoubleEx()
그것은 쉽고 보편적이다!
물론 올바른 로케일을 사용해야 합니다.이 질문이 도움이 될 거예요.
수신된 문자열 값의 로케일을 알 수 없고 현재 기본 로케일과 반드시 같은 로케일이 아닐 경우 다음을 사용할 수 있습니다.
private static double parseDouble(String price){
String parsedStringDouble;
if (price.contains(",") && price.contains(".")){
int indexOfComma = price.indexOf(",");
int indexOfDot = price.indexOf(".");
String beforeDigitSeparator;
String afterDigitSeparator;
if (indexOfComma < indexOfDot){
String[] splittedNumber = price.split("\\.");
beforeDigitSeparator = splittedNumber[0];
afterDigitSeparator = splittedNumber[1];
}
else {
String[] splittedNumber = price.split(",");
beforeDigitSeparator = splittedNumber[0];
afterDigitSeparator = splittedNumber[1];
}
beforeDigitSeparator = beforeDigitSeparator.replace(",", "").replace(".", "");
parsedStringDouble = beforeDigitSeparator+"."+afterDigitSeparator;
}
else {
parsedStringDouble = price.replace(",", "");
}
return Double.parseDouble(parsedStringDouble);
}
문자열의 로케일에 관계없이 이중으로 반환됩니다.쉼표나 점이 몇 개라도 상관없습니다.그래서 지나간다1,000,000.54
효과가 있을 것이다1.000.000,54
따라서 문자열을 구문 분석할 때 기본 로케일에 의존할 필요가 없습니다.코드가 최대한 최적화되어 있지 않기 때문에 어떤 제안이라도 환영합니다.문제가 해결되었는지 확인하기 위해 대부분의 케이스를 테스트해 보았지만, 모든 것을 커버할 수 있을지 모르겠습니다.한계값이 발견되면 알려주세요.
이렇게 하면 됩니다.
Double.parseDouble(p.replace(',','.'));
언급URL : https://stackoverflow.com/questions/4323599/best-way-to-parsedouble-with-comma-as-decimal-separator
'IT이야기' 카테고리의 다른 글
Vuex 스토어 내의 vue-i18n에서 $t를 사용하여 정적 문자열을 초기화하는 방법 (0) | 2022.06.07 |
---|---|
Vuex 작업 유형을 알 수 없는 이유는 무엇입니까? (0) | 2022.06.07 |
Java에서 SoftReference와 WeakReference의 차이점은 무엇입니까? (0) | 2022.06.07 |
memset은 어떻게 정수 배열을 -1로 초기화합니까? (0) | 2022.06.07 |
v-autocomplete 너비를 변경할 수 있습니까? (0) | 2022.06.07 |