Muszę przeanalizować ciąg „1.2345E-02” (liczba wyrażona w notacji wykładniczej) do dziesiętnego typu danych, ale Decimal.Parse("1.2345E-02")
po prostu zgłasza błąd
c#
.net
number-formatting
exponent
Jimbo
źródło
źródło
decimal
zdouble
moim kod działa dobrze dla mnie, tak jak ja go spodziewać. Gdybyś mógł podać szczegóły tego, co próbujesz, kod, którego używasz, i wynik, byłoby znacznie łatwiej pomóc.Oprócz określenia NumberStyles zalecałbym użycie funkcji decimal.TryParse, takiej jak:
decimal result; if( !decimal.TryParse("1.2345E-02", NumberStyles.Any, CultureInfo.InvariantCulture, out result) ) { // do something in case it fails? }
Jako alternatywa dla NumberStyles, możesz użyć określonego zestawu, jeśli masz pewność co do swoich formatów. na przykład:
źródło
decimal d = Decimal.Parse("1.2345E-02", System.Globalization.NumberStyles.Float);
źródło
Zachowaj ostrożność co do wybranej odpowiedzi: istnieje podtemat określający System.Globalization.NumberStyles.Float w Decimal.Parse, który może prowadzić do wyjątku System.FormatException, ponieważ Twój system może oczekiwać na liczbę sformatowaną za pomocą „,” zamiast „”.
Na przykład w notacji francuskiej „1,2345E-02” jest niepoprawne, należy najpierw przekonwertować je na „1,2345E-02”.
Podsumowując, użyj czegoś podobnego do:
Decimal.Parse(valueString.Replace('.',','), System.Globalization.NumberStyles.Float);
źródło
Zauważyłem, że przekazanie
NumberStyles.Float
, w niektórych przypadkach, zmienia reguły, według których przetwarzany jest ciąg i skutkuje innym wyjściem zNumberStyles.Number
(domyślne reguły używane przezdecimal.Parse
).Na przykład poniższy kod wygeneruje
FormatException
w moim komputerze: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
Zalecam użycie danych wejściowych
NumberStyles.Number | NumberStyles.AllowExponent
, ponieważ pozwoli to na liczby wykładnicze i nadal będzie przetwarzać ciąg zgodnie zdecimal
regułami.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
Aby odpowiedzieć na pytanie autora, właściwą odpowiedzią powinno być:
decimal x = decimal.Parse("1.2345E-02", NumberStyles.Number | NumberStyles.AllowExponent); Console.WriteLine(x);
źródło
Ostrzeżenie dotyczące używania NumberStyles.
„6,33E + 03” jest konwertowane zgodnie z oczekiwaniami na 6330. W języku niemieckim kropki dziesiętne są reprezentowane przecinkami, ale 6,33E + 03 konwertuje do 633000! To problem dla moich klientów, ponieważ kultura generująca dane nie jest znana i może być inna niż kultura operująca na danych. W moim przypadku zawsze używam notacji naukowej, więc zawsze mogę zamienić przecinek na przecinek przed analizą, ale jeśli pracujesz z dowolnymi liczbami, takimi jak ładnie sformatowane liczby, takie jak 1,234,567, to podejście nie działa.
źródło
Nie musisz zastępować kropek (odpowiednio przecinków), wystarczy określić wejściowy IFormatProvider:
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"));
źródło
Jeśli chcesz sprawdzić i przekonwertować wartość wykładnika, użyj tego
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); }
Mam nadzieję, że to komuś pomoże.
źródło