Я хочу разобрать строку как "3.5"
в двойной. Тем не мение,
double.Parse("3.5")
дает 35 и
double.Parse("3.5", System.Globalization.NumberStyles.AllowDecimalPoint)
бросает FormatException
.
Теперь локаль моего компьютера установлена на немецкий, где в качестве десятичного разделителя используется запятая. Возможно, придется что-то делать с этим иdouble.Parse()
ожидать в "3,5"
качестве входных данных, но я не уверен.
Как я могу разобрать строку, содержащую десятичное число, которое может или не может быть отформатировано, как указано в моей текущей локали?
Ответы:
источник
XmlConvert
класс ... есть ли у вас идеи, лучше ли это, хуже и / или отличается от использованияCultureInfo.InvariantCulture
?XmlConvert
самом деле не предназначен для анализа одного двойного значения в коде. Я предпочитаю использоватьdouble.Parse
илиConvert.ToDouble
это делает мое намерение очевидным.Обычно я использую мультикультурную функцию для анализа ввода пользователя, главным образом потому, что если кто-то привык к цифровой клавиатуре и использует культуру, в которой в качестве десятичного разделителя используется запятая, этот человек будет использовать точку цифровой клавиатуры вместо запятой.
Но будьте осторожны, комментарии @nikie верны. В свою защиту я использую эту функцию в контролируемой среде, где я знаю, что культура может быть либо en-US, en-CA, либо fr-CA. Я использую эту функцию, потому что на французском языке мы используем запятую в качестве десятичного разделителя, но любой, кто когда-либо работал в финансах, всегда будет использовать десятичный разделитель на цифровой клавиатуре, но это точка, а не запятая. Так что даже в культуре fr-CA мне нужно проанализировать число, которое будет иметь точку в качестве десятичного разделителя.
источник
Я не мог написать комментарий, поэтому я пишу здесь:
double.Parse ("3.5", CultureInfo.InvariantCulture) не очень хорошая идея, потому что в Канаде мы пишем 3,5 вместо 3,5, и в результате эта функция дает нам 35.
Я проверил оба на моем компьютере:
Это правильный путь, о котором упоминал Пьер-Ален Вижан
источник
Замените запятую точкой перед разбором. Полезно в странах с запятой в качестве десятичного разделителя. Подумайте об ограничении пользовательского ввода (при необходимости) одной запятой или точкой.
источник
Хитрость в том, чтобы использовать инвариантную культуру, чтобы разбирать точки во всех культурах.
источник
Посмотрите, каждый ответ выше, который предлагает написать замену строки константной строкой, может быть только неправильным. Зачем? Потому что вы не уважаете региональные настройки Windows! Windows гарантирует пользователю свободу установки любого символа разделителя, который он / она хочет. Он / она может открыть панель управления, перейти на панель региона, нажать на кнопку «Дополнительно» и изменить персонажа в любое время. Даже во время вашей программы. Подумай об этом. Хорошее решение должно знать об этом.
Итак, сначала вам нужно спросить себя, откуда этот номер, который вы хотите проанализировать. Если он поступает из ввода в .NET Framework, нет проблем, потому что он будет в том же формате. Но, возможно, это было извне, может быть, с внешнего сервера, может быть, из старой БД, которая поддерживает только строковые свойства. Там администратор БД должен был дать правило, в каком формате должны храниться числа. Например, если вы знаете, что это будет БД США в американском формате, вы можете использовать этот фрагмент кода:
Это будет хорошо работать в любой точке мира. И, пожалуйста, не используйте «Convert.ToXxxx». Класс «Преобразование» рассматривается только как основа для преобразований в любом направлении. Кроме того: Вы можете использовать аналогичный механизм и для DateTimes.
источник
источник
Мои два цента на эту тему, пытаясь обеспечить общий метод двойного преобразования:
Работает как положено с:
Преобразование по умолчанию не будет реализовано, поэтому он потерпит неудачу , пытаясь разобрать
1.3,14
,1,3.14
или подобные случаи.источник
Следующий код делает работу в любом сценарии. Это немного разбор.
источник
Я думаю, что 100% правильное преобразование невозможно, если значение поступает из пользовательского ввода. например, если значение равно 123.456, это может быть группировка или десятичная точка. Если вам действительно нужно 100%, вы должны описать свой формат и выдать исключение, если оно не является правильным.
Но я улучшил код JanW, поэтому мы немного опередили 100%. Идея заключается в том, что если последний разделитель является groupSeperator, это будет больше целочисленный тип, чем двойной.
Добавленный код в первом случае из GetDouble .
источник
источник
Вместо того, чтобы указывать языковой стандарт во всех синтаксических анализах, я предпочитаю устанавливать языковой стандарт для всего приложения, хотя, если строковые форматы не согласованы в приложении, это может не сработать.
Если вы укажете это в начале вашего приложения, все двойные синтаксические разборки будут ожидать запятую в качестве десятичного разделителя. Вы можете установить соответствующий языковой стандарт, чтобы десятичный разделитель и разделитель тысяч соответствовали строкам, которые вы анализируете.
источник
Это сложно без указания того, какой десятичный разделитель искать, но если вы это сделаете, то я использую:
Это должно работать с любой культурой. Он не может правильно проанализировать строки, содержащие более одного десятичного разделителя, в отличие от реализаций, которые заменяют вместо swap.
источник
Я также улучшил код @JanW ...
Мне это нужно для форматирования результатов медицинских инструментов, и они также отправляют "> 1000", "23.3e02", "350E-02" и "ОТРИЦАТЕЛЬНЫЙ".
источник
источник
Я думаю, что это лучший ответ:
источник
Ниже менее эффективно, но я использую эту логику. Это действительно только если у вас есть две цифры после десятичной точки.
источник
Умножьте число, а затем разделите его на то, на что вы умножили его ранее.
Например,
источник