소수점을 2배로 하는 문자열을 해석하려면 어떻게 해야 하나요?
는 음음음음음 like like like like like like like like like like like like 같은 문자열을 해석하고 싶다."3.5"단 ★★★★★★★★★★★★★★★★★★★.
double.Parse("3.5")
산출량 35 및
double.Parse("3.5", System.Globalization.NumberStyles.AllowDecimalPoint)
FormatException.
이제 컴퓨터의 로케일은 독일어로 설정되었으며 쉼표는 소수 구분 기호로 사용됩니다.랑 뭔가 가 있을 수도 double.Parse() ''"3,5"정확히는 모르겠지만
현재 로케일에서 지정된 형식과 다를 수 있는 10진수를 포함하는 문자열을 해석하려면 어떻게 해야 합니까?
double.Parse("3.5", CultureInfo.InvariantCulture)
저는 보통 멀티컬처 함수를 사용하여 사용자 입력을 해석합니다.이는 주로 숫자패드에 익숙하고 소수 구분자로 쉼표를 사용하는 문화를 사용하는 경우 쉼표 대신 숫자패드의 포인트를 사용하기 때문입니다.
public static double GetDouble(string value, double defaultValue)
{
double result;
//Try parsing in the current culture
if (!double.TryParse(value, System.Globalization.NumberStyles.Any, CultureInfo.CurrentCulture, out result) &&
//Then try in US english
!double.TryParse(value, System.Globalization.NumberStyles.Any, CultureInfo.GetCultureInfo("en-US"), out result) &&
//Then in neutral language
!double.TryParse(value, System.Globalization.NumberStyles.Any, CultureInfo.InvariantCulture, out result))
{
result = defaultValue;
}
return result;
}
하지만 주의하세요. @nikie 댓글은 진실입니다.제 변명을 하자면, 저는 이 기능을 문화가 en-US, en-CA 또는 fr-CA 중 하나라는 것을 아는 통제된 환경에서 사용합니다.이 함수를 사용하는 이유는 프랑스어에서는 콤마를 소수 구분자로 사용하지만 재무직 종사자는 항상 숫자패드에서 소수 구분자를 사용하지만 이것은 쉼표가 아니라 포인트입니다.따라서 fr-CA 문화에서도 소수점 구분자로서의 포인트가 되는 번호를 해석해야 합니다.
코멘트를 쓸 수 없어서 여기에 씁니다.
double.Parse("3.5"), CultureInfo.UniversentCulture)는 좋은 생각이 아닙니다.캐나다에서는 3.5가 아닌 3.5로 표기되며 이 함수는 35를 제공하기 때문입니다.
컴퓨터에서 두 가지 테스트를 모두 실시했습니다.
double.Parse("3.5", CultureInfo.InvariantCulture) --> 3.5 OK
double.Parse("3,5", CultureInfo.InvariantCulture) --> 35 not OK
이것은 피에르 알랭 비제앙이 말한 올바른 방법이다.
public static double GetDouble(string value, double defaultValue)
{
double result;
// Try parsing in the current culture
if (!double.TryParse(value, System.Globalization.NumberStyles.Any, CultureInfo.CurrentCulture, out result) &&
// Then try in US english
!double.TryParse(value, System.Globalization.NumberStyles.Any, CultureInfo.GetCultureInfo("en-US"), out result) &&
// Then in neutral language
!double.TryParse(value, System.Globalization.NumberStyles.Any, CultureInfo.InvariantCulture, out result))
{
result = defaultValue;
}
return result;
}
Double.Parse("3,5".Replace(',', '.'), CultureInfo.InvariantCulture)
해석하기 전에 쉼표를 점으로 바꿉니다.쉼표를 소수 구분 기호로 사용하는 국가에서 유용합니다.사용자 입력(필요한 경우)을 하나의 쉼표 또는 점으로 제한합니다.
문자열 치환을 상수 문자열로 쓰자는 위의 답변은 모두 틀릴 수 밖에 없어요. 왜요?Windows의 지역 설정을 존중하지 않기 때문입니다.Windows 에서는, 유저가 원하는 구분 문자를 자유롭게 설정할 수 있습니다.제어판을 열고 지역 패널로 이동하여 [Advanced]를 클릭하여 언제든지 문자를 변경할 수 있습니다.프로그램 실행 중에도 마찬가지입니다.생각해 보세요.좋은 해결책은 이 점을 알고 있어야 합니다.
따라서 먼저 이 번호의 출처가 어디인지, 해석하고 싶은지 자문해 보아야 합니다.에 입력되어 있는 경우.NET Framework는 같은 형식이므로 문제 없습니다.그러나 외부 서버나 문자열 속성만 지원하는 오래된 DB에서 온 것일 수 있습니다.여기서 db 관리자는 번호를 저장하는 형식의 규칙을 지정해야 합니다.예를 들어 US 형식의 US DB라는 것을 알고 있다면 다음 코드를 사용할 수 있습니다.
CultureInfo usCulture = new CultureInfo("en-US");
NumberFormatInfo dbNumberFormat = usCulture.NumberFormat;
decimal number = decimal.Parse(db.numberString, dbNumberFormat);
이것은 세계 어디에서나 잘 작동될 것이다.그리고 'Convert'는 사용하지 마세요.To Xxx' 입니다.'Convert' 클래스는 모든 방향의 변환 기준으로만 간주됩니다.기타:DateTimes에서도 같은 메커니즘을 사용할 수 있습니다.
비결은 불변의 문화를 사용하여 모든 문화에서 점을 분석하는 것입니다.
double.Parse("3.5", System.Globalization.NumberStyles.AllowDecimalPoint, System.Globalization.NumberFormatInfo.InvariantInfo);
string testString1 = "2,457";
string testString2 = "2.457";
double testNum = 0.5;
char decimalSepparator;
decimalSepparator = testNum.ToString()[1];
Console.WriteLine(double.Parse(testString1.Replace('.', decimalSepparator).Replace(',', decimalSepparator)));
Console.WriteLine(double.Parse(testString2.Replace('.', decimalSepparator).Replace(',', decimalSepparator)));
일반적인 이중 변환 방법을 제공하려는 이 주제에 대한 나의 의견:
private static double ParseDouble(object value)
{
double result;
string doubleAsString = value.ToString();
IEnumerable<char> doubleAsCharList = doubleAsString.ToList();
if (doubleAsCharList.Where(ch => ch == '.' || ch == ',').Count() <= 1)
{
double.TryParse(doubleAsString.Replace(',', '.'),
System.Globalization.NumberStyles.Any,
CultureInfo.InvariantCulture,
out result);
}
else
{
if (doubleAsCharList.Where(ch => ch == '.').Count() <= 1
&& doubleAsCharList.Where(ch => ch == ',').Count() > 1)
{
double.TryParse(doubleAsString.Replace(",", string.Empty),
System.Globalization.NumberStyles.Any,
CultureInfo.InvariantCulture,
out result);
}
else if (doubleAsCharList.Where(ch => ch == ',').Count() <= 1
&& doubleAsCharList.Where(ch => ch == '.').Count() > 1)
{
double.TryParse(doubleAsString.Replace(".", string.Empty).Replace(',', '.'),
System.Globalization.NumberStyles.Any,
CultureInfo.InvariantCulture,
out result);
}
else
{
throw new ParsingException($"Error parsing {doubleAsString} as double, try removing thousand separators (if any)");
}
}
return result;
}
예상대로 동작:
- 1.1
- 1,1
- 1,000,000,000
- 1.000.000.000
- 1,000,000,000.99
- 1.000.000.000,99
- 5,000,111.3
- 5.000.111,3
- 0.99,000,111,88
- 0,99.000.111.88
않기 합니다.1.3,14,1,3.14또는 유사한 경우.
다음 코드는 모든 시나리오에서 작업을 수행합니다.약간 구문 분석입니다.
List<string> inputs = new List<string>()
{
"1.234.567,89",
"1 234 567,89",
"1 234 567.89",
"1,234,567.89",
"123456789",
"1234567,89",
"1234567.89",
};
string output;
foreach (string input in inputs)
{
// Unify string (no spaces, only .)
output = input.Trim().Replace(" ", "").Replace(",", ".");
// Split it on points
string[] split = output.Split('.');
if (split.Count() > 1)
{
// Take all parts except last
output = string.Join("", split.Take(split.Count()-1).ToArray());
// Combine token parts with last part
output = string.Format("{0}.{1}", output, split.Last());
}
// Parse double invariant
double d = double.Parse(output, CultureInfo.InvariantCulture);
Console.WriteLine(d);
}
100% 정확한 변환은 불가능하다고 생각합니다.예를 들어, 값이 123.456이면 그룹화 또는 소수점일 수 있습니다.100%가 필요한 경우 형식을 설명하고 올바르지 않은 경우 예외를 두어야 합니다.
하지만 저는 JanW의 코드를 개선했습니다. 그래서 우리는 100%를 조금 더 앞서가고 있습니다.마지막 구분자가 groupSeperator일 경우, 이는 이중형이 아니라 정수형이 됩니다.
추가된 코드는 GetDouble의 첫 번째 if에 있습니다.
void Main()
{
List<string> inputs = new List<string>() {
"1.234.567,89",
"1 234 567,89",
"1 234 567.89",
"1,234,567.89",
"1234567,89",
"1234567.89",
"123456789",
"123.456.789",
"123,456,789,"
};
foreach(string input in inputs) {
Console.WriteLine(GetDouble(input,0d));
}
}
public static double GetDouble(string value, double defaultValue) {
double result;
string output;
// Check if last seperator==groupSeperator
string groupSep = System.Globalization.CultureInfo.CurrentCulture.NumberFormat.NumberGroupSeparator;
if (value.LastIndexOf(groupSep) + 4 == value.Count())
{
bool tryParse = double.TryParse(value, System.Globalization.NumberStyles.Any, System.Globalization.CultureInfo.CurrentCulture, out result);
result = tryParse ? result : defaultValue;
}
else
{
// Unify string (no spaces, only . )
output = value.Trim().Replace(" ", string.Empty).Replace(",", ".");
// Split it on points
string[] split = output.Split('.');
if (split.Count() > 1)
{
// Take all parts except last
output = string.Join(string.Empty, split.Take(split.Count()-1).ToArray());
// Combine token parts with last part
output = string.Format("{0}.{1}", output, split.Last());
}
// Parse double invariant
result = double.Parse(output, System.Globalization.CultureInfo.InvariantCulture);
}
return result;
}
var doublePattern = @"(?<integer>[0-9]+)(?:\,|\.)(?<fraction>[0-9]+)";
var sourceDoubleString = "03444,44426";
var match = Regex.Match(sourceDoubleString, doublePattern);
var doubleResult = match.Success ? double.Parse(match.Groups["integer"].Value) + (match.Groups["fraction"].Value == null ? 0 : double.Parse(match.Groups["fraction"].Value) / Math.Pow(10, match.Groups["fraction"].Value.Length)): 0;
Console.WriteLine("Double of string '{0}' is {1}", sourceDoubleString, doubleResult);
모든 구문에서 로케일을 지정하는 대신 애플리케이션 전체 로케일을 설정하는 것이 좋습니다. 단, 앱 전체에서 문자열 형식이 일관되지 않으면 작동하지 않을 수 있습니다.
CultureInfo.DefaultThreadCurrentCulture = new CultureInfo("pt-PT");
CultureInfo.DefaultThreadCurrentUICulture = new CultureInfo("pt-PT");
응용 프로그램 시작 부분에서 이 값을 정의하면 모든 이중 구문에서 쉼표가 소수 구분 기호로 지정됩니다.해석하는 문자열에 적합하도록 10진수 구분 기호와 수천 구분 기호로 적절한 로케일을 설정할 수 있습니다.
찾을 소수 구분 기호를 지정하지 않으면 어렵지만, 찾을 경우 다음과 같이 입력합니다.
public static double Parse(string str, char decimalSep)
{
string s = GetInvariantParseString(str, decimalSep);
return double.Parse(s, System.Globalization.CultureInfo.InvariantCulture);
}
public static bool TryParse(string str, char decimalSep, out double result)
{
// NumberStyles.Float | NumberStyles.AllowThousands got from Reflector
return double.TryParse(GetInvariantParseString(str, decimalSep), NumberStyles.Float | NumberStyles.AllowThousands, System.Globalization.CultureInfo.InvariantCulture, out result);
}
private static string GetInvariantParseString(string str, char decimalSep)
{
str = str.Replace(" ", "");
if (decimalSep != '.')
str = SwapChar(str, decimalSep, '.');
return str;
}
public static string SwapChar(string value, char from, char to)
{
if (value == null)
throw new ArgumentNullException("value");
StringBuilder builder = new StringBuilder();
foreach (var item in value)
{
char c = item;
if (c == from)
c = to;
else if (c == to)
c = from;
builder.Append(c);
}
return builder.ToString();
}
private static void ParseTestErr(string p, char p_2)
{
double res;
bool b = TryParse(p, p_2, out res);
if (b)
throw new Exception();
}
private static void ParseTest(double p, string p_2, char p_3)
{
double d = Parse(p_2, p_3);
if (d != p)
throw new Exception();
}
static void Main(string[] args)
{
ParseTest(100100100.100, "100.100.100,100", ',');
ParseTest(100100100.100, "100,100,100.100", '.');
ParseTest(100100100100, "100.100.100.100", ',');
ParseTest(100100100100, "100,100,100,100", '.');
ParseTestErr("100,100,100,100", ',');
ParseTestErr("100.100.100.100", '.');
ParseTest(100100100100, "100 100 100 100.0", '.');
ParseTest(100100100.100, "100 100 100.100", '.');
ParseTest(100100100.100, "100 100 100,100", ',');
ParseTest(100100100100, "100 100 100,100", '.');
ParseTest(1234567.89, "1.234.567,89", ',');
ParseTest(1234567.89, "1 234 567,89", ',');
ParseTest(1234567.89, "1 234 567.89", '.');
ParseTest(1234567.89, "1,234,567.89", '.');
ParseTest(1234567.89, "1234567,89", ',');
ParseTest(1234567.89, "1234567.89", '.');
ParseTest(123456789, "123456789", '.');
ParseTest(123456789, "123456789", ',');
ParseTest(123456789, "123.456.789", ',');
ParseTest(1234567890, "1.234.567.890", ',');
}
이것은 어떤 문화에서도 통할 것입니다.스왑 대신 교체되는 구현과 달리 여러 개의 소수 구분 기호가 있는 문자열은 올바르게 구문 분석되지 않습니다.
@JanW의 코드도 개선했습니다...
의료기기 결과를 포맷하기 위해 필요한데, ">1000", "23.3e02", "350E-02", "Negative"도 보내오고 있습니다.
private string FormatResult(string vResult)
{
string output;
string input = vResult;
// Unify string (no spaces, only .)
output = input.Trim().Replace(" ", "").Replace(",", ".");
// Split it on points
string[] split = output.Split('.');
if (split.Count() > 1)
{
// Take all parts except last
output = string.Join("", split.Take(split.Count() - 1).ToArray());
// Combine token parts with last part
output = string.Format("{0}.{1}", output, split.Last());
}
string sfirst = output.Substring(0, 1);
try
{
if (sfirst == "<" || sfirst == ">")
{
output = output.Replace(sfirst, "");
double res = Double.Parse(output);
return String.Format("{1}{0:0.####}", res, sfirst);
}
else
{
double res = Double.Parse(output);
return String.Format("{0:0.####}", res);
}
}
catch
{
return output;
}
}
다음은 쉼표와 마침표를 포함한 숫자 문자열을 처리하는 솔루션입니다.이 솔루션은 금액에 특화되어 있기 때문에 10분의 1, 100분의 1만 예상됩니다.그 이상은 정수로 취급됩니다.
먼저 숫자, 쉼표, 마침표 또는 음수 기호가 아닌 것을 제거합니다.
string stringAmount = Regex.Replace(originalString, @"[^0-9\.\-,]", "");
그런 다음 정수와 십진수로 나눕니다.
string[] decimalParsed = Regex.Split(stringAmount, @"(?:\.|,)(?=\d{2}$)");
(이 정규식은 문자열의 끝에서2개의 숫자인 쉼표 또는 마침표를 선택합니다).
이제 전체 숫자를 가져와서 쉼표와 마침표를 제거합니다.
string wholeAmount = decimalParsed[0].Replace(",", "").Replace(".", "");
if (wholeAmount.IsNullOrEmpty())
wholeAmount = "0";
이제 소수점 부분은 취급합니다(있는 경우.
string decimalAmount = "00";
if (decimalParsed.Length == 2)
{
decimalAmount = decimalParsed[1];
}
마지막으로 전체와 소수점을 합산하여 Double을 구문 분석할 수 있습니다.
double amount = $"{wholeAmount}.{decimalAmount}".ToDouble();
이것은 200,00,1000,00,1000,1000, 1.000,33, 2,000.000,78 등을 처리합니다.
개발 중입니다.Windows, Mac, Android 및 iPhone에서 실행되는 Net Maui 앱.위도, 경도, 고도 등 모든 경우에 '.'를 사용하여 구문 분석하고 저장하는 이중 값이 3개 있습니다.마침 안드로이드와 아이폰을 스페인어로 설정했는데 안드로이드가 '.' 문자열을 잘 해석하는 것을 알게 되었습니다.그러나 아이폰은 내가 ''를 ''로 대체하지 않는 한 올바르게 해석하기를 거부했다.그렇지 않으면 결과는 항상 엄청난 숫자였다.
현지화의 복잡함에 대처하기보다는, 이중 번호의 특정 한계를 활용하는 간단한 해결책을 생각해 냈습니다.
case "Lat":
waypoint.Lat = ParseDouble(xmlVal, 90);
break;
case "Lon":
waypoint.Lon = ParseDouble(xmlVal, 180);
break;
case "Alt":
waypoint.Alt = ParseDouble(xmlVal, 32000);
public static double ParseDouble(string val, double limit)
{
double result;
if (double.TryParse(val, out result))
{
if (Math.Abs(result) <= limit)
return result;
else if (double.TryParse(val.Replace('.', ','), out result))
{
if (Math.Abs(result) <= limit)
return result;
}
}
return 0;
}
System.Globalization.CultureInfo ci = System.Globalization.CultureInfo.CurrentCulture;
string _pos = dblstr.Replace(".",
ci.NumberFormat.NumberDecimalSeparator).Replace(",",
ci.NumberFormat.NumberDecimalSeparator);
double _dbl = double.Parse(_pos);
아래는 효율이 떨어지지만, 저는 이 논리를 사용합니다.이것은 소수점 뒤에 두 자리 숫자가 있는 경우에만 유효합니다.
double val;
if (temp.Text.Split('.').Length > 1)
{
val = double.Parse(temp.Text.Split('.')[0]);
if (temp.Text.Split('.')[1].Length == 1)
val += (0.1 * double.Parse(temp.Text.Split('.')[1]));
else
val += (0.01 * double.Parse(temp.Text.Split('.')[1]));
}
else
val = double.Parse(RR(temp.Text));
숫자를 곱한 다음 이전에 곱한 수로 나누세요.
예를들면,
perc = double.Parse("3.555)*1000;
result = perc/1000
언급URL : https://stackoverflow.com/questions/1354924/how-do-i-parse-a-string-with-a-decimal-point-to-a-double
'programing' 카테고리의 다른 글
| WPF에서 콤보박스 컨트롤에 열거형을 바인드하려면 어떻게 해야 합니까? (0) | 2023.04.09 |
|---|---|
| HSSF(Apache POI)를 사용하여 기존 Excel에서 두 줄 사이에 행을 삽입하는 방법 (0) | 2023.04.09 |
| -performSelector:withObject:afterDelay:와 같이 지연 후에 블록을 트리거하려면 어떻게 해야 합니까? (0) | 2023.04.09 |
| 오류: "INSERT EXEC 문을 중첩할 수 없습니다." 및 "INSERT-EXEC 문 내에서 ROLLBLL 문을 사용할 수 없습니다."어떻게 해결할까요? (0) | 2023.04.09 |
| Swift3에서 fileprivate와 private를 구별하는 좋은 예는 무엇입니까? (0) | 2023.04.09 |