"1.2345E-02" dizesini (üstel gösterimle ifade edilen bir sayı) bir ondalık veri türüne ayrıştırmam gerekiyor, ancak Decimal.Parse("1.2345E-02")
yalnızca bir hata veriyor
Yanıtlar:
Bu bir kayan nokta sayısıdır, ona şunu söylemelisiniz:
decimal d = Decimal.Parse("1.2345E-02", System.Globalization.NumberStyles.Float);
Şunları belirtirseniz çalışır NumberStyles.Float
:
decimal x = decimal.Parse("1.2345E-02", NumberStyles.Float);
Console.WriteLine(x); // Prints 0.012345
Bunun neden varsayılan olarak desteklenmediğinden tam olarak emin değilim - varsayılan, NumberStyles.Number
AllowLeadingWhite, AllowTrailingWhite, AllowLeadingSign, AllowTrailingSign, AllowDecimalPoint ve AllowThousands stillerini kullanan kullanmaktır . Muhtemelen performansla ilgilidir; bir üs belirtmek nispeten nadirdir, sanırım.
decimal
ile değiştirmek , double
beklediğim gibi benim için iyi çalışıyor. Verdiğiniz olsaydı ayrıntıları sen çalışıyorsun şeyin, kullandığınız kod ve sonuç, bu yardımı çok daha kolay olurdu.
NumberStyles'ı belirtmenin yanı sıra, decimal. TryParse işlevini kullanmanızı tavsiye ederim, örneğin:
decimal result;
if( !decimal.TryParse("1.2345E-02", NumberStyles.Any, CultureInfo.InvariantCulture, out result) )
{
// do something in case it fails?
}
NumberStyles'a alternatif olarak, biçimlerinizden eminseniz, belirli bir set kullanabilirsiniz. Örneğin:
NumberStyles.AllowExponent | NumberStyles.Float
decimal d = Decimal.Parse("1.2345E-02", System.Globalization.NumberStyles.Float);
Seçilen yanıt konusunda dikkatli olun: System.Globalization.NumberStyles.Float in Decimal.Parse öğesini belirten bir alt yetenek vardır ve bu bir System.FormatException sonucuna yol açabilir çünkü sisteminiz "yerine", "ile biçimlendirilmiş bir sayı bekliyor olabilir.
Örneğin, fransızca gösterimde "1.2345E-02" geçersizdir, önce "1,2345E-02" ye dönüştürmelisiniz.
Sonuç olarak, şu satırlar boyunca bir şey kullanın:
Decimal.Parse(valueString.Replace('.',','), System.Globalization.NumberStyles.Float);
NumberStyles.Float
Bazı durumlarda içeri aktarmanın, dizenin işlendiği kuralları değiştirdiğini ve bundan farklı bir çıktıyla sonuçlandığını buldum NumberStyles.Number
(tarafından kullanılan varsayılan kurallardecimal.Parse
).
Örneğin, aşağıdaki kod FormatException
makinemde bir oluşturacak :
CultureInfo culture = new CultureInfo("");
culture.NumberFormat.NumberDecimalDigits = 2;
culture.NumberFormat.NumberDecimalSeparator = ".";
culture.NumberFormat.NumberGroupSeparator = ",";
Decimal.Parse("1,234.5", NumberStyles.Float, culture); // FormatException thrown here
Girişi kullanmanızı tavsiye ederim NumberStyles.Number | NumberStyles.AllowExponent
, çünkü bu üstel sayılara izin verecek ve dizeyi decimal
kurallara göre işleyecektir .
CultureInfo culture = new CultureInfo("");
culture.NumberFormat.NumberDecimalDigits = 2;
culture.NumberFormat.NumberDecimalSeparator = ".";
culture.NumberFormat.NumberGroupSeparator = ",";
Decimal.Parse("1,234.5",NumberStyles.Number | NumberStyles.AllowExponent, culture); // Does not generate a FormatException
Posterin sorusuna cevap vermek için doğru cevap şu şekilde olmalıdır:
decimal x = decimal.Parse("1.2345E-02", NumberStyles.Number | NumberStyles.AllowExponent);
Console.WriteLine(x);
NumberStyles.Any kullanımıyla ilgili uyarı:
"6.33E + 03", beklendiği gibi 6330'a dönüşür. Almanca'da ondalık basamaklar virgülle temsil edilir, ancak 6,33E + 03 633000'e dönüştürülür! Verileri oluşturan kültür bilinmediğinden ve veriler üzerinde işleyen kültürden farklı olabileceğinden, bu müşterilerim için bir sorundur. Benim durumumda, her zaman bilimsel gösterime sahibim, bu yüzden ayrıştırmadan önce her zaman virgül yerine ondalık virgül koyabilirim, ancak 1,234,567 gibi güzel biçimlendirilmiş sayılar gibi keyfi sayılarla çalışıyorsanız, o zaman bu yaklaşım işe yaramaz.
Noktaları (sırasıyla virgül) değiştirmeniz gerekmez, sadece IFormatProvider girişini belirtin:
float d = Single.Parse("1.27315", System.Globalization.NumberStyles.Float, new CultureInfo("en-US"));
float d = Single.Parse("1,27315", System.Globalization.NumberStyles.Float, new CultureInfo("de-DE"));
Üs değerini kontrol etmek ve dönüştürmek istiyorsanız bunu kullanın
string val = "1.2345E-02";
double dummy;
bool hasExponential = (val.Contains("E") || val.Contains("e")) && double.TryParse(val, out dummy);
if (hasExponential)
{
decimal d = decimal.Parse(val, NumberStyles.Float);
}
Umarım bu birine yardımcı olur.
Varsayılan NumberStyle
için decimal.Parse(String)
, NumberStyles.Number
üslere izin vermek için işlevselliği eklemek istiyorsanız, eklemek için bit düzeyinde VEYA yapabilirsiniz NumberStyles.AllowExponent
.
decimal d = decimal
.Parse("1.2345E-02", NumberStyles.Number | NumberStyles.AllowExponent);