Разобрать число из экспоненциальной записи

Мне нужно проанализировать строку "1.2345E-02" (число, выраженное в экспоненциальной записи) в десятичный тип данных, ноDecimal.Parse("1.2345E-02") просто выдает ошибку

Ответы на вопрос(7)

атьdecimal.TryParse функция, такая как:

decimal result;
if( !decimal.TryParse("1.2345E-02", NumberStyles.Any, CultureInfo.InvariantCulture, out result) )
{
     // do something in case it fails?
}

В качестве альтернативы NumberStyles.Any вы можете использовать определенный набор, если вы уверены в своих форматах. например:

NumberStyles.AllowExponent | NumberStyles.Float
 Lukáš Kmoch31 мар. 2017 г., 10:39
Но не обязательно использовать Float с AllowExponent, потому что Float = AllowLeadingWhite | AllowTrailingWhite | AllowLeadingSign | AllowDecimalPoint | AllowExponent
 Sverrir Sigmundarson31 мар. 2017 г., 17:57
@ LukášKmoch Действительно, ты прав. Сила привычки, так как остальные (кроме Любой) не включают ее. Не должно быть больно выполнять дополнительное ИЛИ, хотя.

NumberStyles.Floatв некоторых случаях изменяет правила, по которым обрабатывается строка, и приводит к другому выводу изNumberStyles.Number (правила по умолчанию, используемыеdecimal.Parse).

Например, следующий код сгенерируетFormatException в моей машине:

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

Я бы рекомендовал использовать входNumberStyles.Number | NumberStyles.AllowExponent, так как это позволит экспоненциальных чисел и будет по-прежнему обрабатывать строку подdecimal правила.

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

Чтобы ответить на вопрос автора, правильный ответ должен быть следующим:

decimal x = decimal.Parse("1.2345E-02", NumberStyles.Number | NumberStyles.AllowExponent);
Console.WriteLine(x);

System.Globalization.NumberStyles.Float вDecimal.Parse что может привести кSystem.FormatException потому что ваша система может ожидать число, форматированное с «,» вместо «.»

Например, во французской нотации «1.2345E-02» недопустим, вы должны сначала преобразовать его в «1,2345E-02».

В заключение, используйте что-то вроде:

Decimal.Parse(valueString.Replace('.',','), System.Globalization.NumberStyles.Float);
 Carles Alcolea05 янв. 2017 г., 08:00
Вы абсолютно правы. Я не понимаю, почему никто не поднял это.
 Andriy Kozachuk12 нояб. 2017 г., 14:36
Лучше использовать CultureInfo.InvariantCulture в качестве 3-го параметра Parse

Это работает, если вы укажетеNumberStyles.Float:

decimal x = decimal.Parse("1.2345E-02", NumberStyles.Float);
Console.WriteLine(x); // Prints 0.012345

Я не совсем уверен, почему это не поддерживается по умолчанию - по умолчанию используетсяNumberStyles.Number, который использует стили AllowLeadingWhite, AllowTrailingWhite, AllowLeadingSign, AllowTrailingSign, AllowDecimalPoint и AllowThousands. Возможно, это связано с производительностью; указание показателя степениотносительно я полагаю, редко.

 Jon Skeet05 авг. 2019 г., 20:36
@JanT: не имея больше информации, чем «не будет» и «не может», я не могу больше помочь. Я предлагаю вам задать новый вопрос с гораздо более подробной информацией, показывая, что вы пытались и что именно произошло.
 JanT05 авг. 2019 г., 21:32
Я пытался запустить код, как в вашем ответе, но вместо десятичного используется двойной. Но уже нашли обходной путь. ура
 JanT05 авг. 2019 г., 16:01
Я пытаюсь заставить это работать с двойным, но кажется, что это не будет. Не уверен, почему это не могло ..?

«6.33E + 03» преобразуется в 6330, как и ожидалось. На немецком языке десятичные точки представлены запятыми, но 6,33E + 03 преобразуется в 633000! Это проблема для моих клиентов, так как культура, которая генерирует данные, неизвестна и может отличаться от культуры, которая работает с данными. В моем случае у меня всегда есть научная нотация, поэтому я всегда могу заменить запятую на десятичную точку перед анализом, но если вы работаете с произвольными числами, такими как довольно отформатированные числа, такие как 1 234 567, то такой подход не работает.

Решение Вопроса

decimal d = Decimal.Parse("1.2345E-02", System.Globalization.NumberStyles.Float);
decimal d = Decimal.Parse("1.2345E-02", System.Globalization.NumberStyles.Float);

Ваш ответ на вопрос