Почему я получаю исключение FormatException при преобразовании строки в число с плавающей точкой? - PullRequest
13 голосов
/ 08 апреля 2011

Когда я пытаюсь преобразовать строку в число с плавающей точкой:

Console.WriteLine(float.Parse("6.59"));

выдает исключение:

Необработанное исключение: System.FormatException: входная строка невернаf ormat.
at System.Number.ParseSingle (String value, NumberStyles options, NumberFormat Info numfmt)

Когда я пытаюсь сделать это следующим образом:

Console.WriteLine(Convert.ToSingle("6.59"));

Выдаетто же исключение:

Необработанное исключение: System.FormatException: входная строка не соответствует правильному формату.
в System.Number.ParseSingle (строковое значение, параметры NumberStyles, NumberFormat Info numfmt)
в System.Convert.ToSingle (String value)

Можете ли вы объяснить, почему это происходит?

Ответы [ 7 ]

36 голосов
/ 08 апреля 2011

Метод Parse с одним аргументом использует текущую культуру для анализа строки. Если ваша текущая культура использует какой-либо другой десятичный разделитель, это не удастся.

Попробуйте использовать инвариантную культуру:

float.Parse("6.59", CultureInfo.InvariantCulture)
4 голосов
/ 08 апреля 2011

Проблема здесь в вашей культуре.

Либо установите инвариантную культуру следующим образом:

float.Parse("6.59", CultureInfo.InvariantCulture)

, либо используйте правильный десятичный разделитель для вашей культуры

float.Parse("6,59")

Интересно, почему вы используете буквальную строку?Если у вас возникают проблемы при вводе буквенных чисел, вы можете использовать

Console.WriteLine(6.59f)

Если вы делаете это таким образом, культура не имеет значения, потому что значение определяется во время компиляции.

3 голосов
/ 08 апреля 2011

Возможно, вы используете культуру, в которой в качестве десятичного разделителя используется ,.

Вы можете попробовать Разобрать , используя InvariantCulture :

float.Parse("6.59", CultureInfo.InvariantCulture)
2 голосов
/ 08 апреля 2011

Культура - специфические вещи.Какая у вас культура по умолчанию?Некоторые культуры используют «,» вместо «.».Вы можете попробовать это:

float.Parse("6.59", CultureInfo.InvariantCulture);
2 голосов
/ 08 апреля 2011

Может быть проблема с языком / культурой. Вам нужно установить , вместо . для десятичного разделителя.

1 голос
/ 11 декабря 2016

Я знаю, что все здесь уже объяснили причину возникшей проблемы, но, возможно, кто-то должен просто рассказать, почему Invariant исправляет ее.

Класс CultureInfo используется прямо или косвенно классами, которые форматируют, анализируют или манипулируют данными, относящимися к культуре, такими как String, DateTime, DateTimeOffset и числовые типы, чтобы справляться с различиями в способе написания этих разных культур. типы.

В случае десятичного типа некоторые культуры используют точку (.), В то время как другие используют запятую (,). По умолчанию, когда вы используете библиотеки преобразования, он будет использовать вашу местную культуру (то есть страну, для которой настроена ваша ОС).

Указывая Invariant, вы говорите, что ожидаете, что тысячи разделителей будут запятыми (,), а десятичный разделитель - точкой (.), Как в большинстве культур.

Большая проблема, которая иногда возникает, заключается в том, что эти культурные соглашения меняются с точки зрения ОС. Например, информация о культуре Южной Африки (ZA) использовалась как инвариантная культура. Microsoft изменила это в Windows 8, где десятичная дробь внезапно стала запятой, а разделитель тысяч - пробелом. Это привело к тому, что многие устаревшие системы, написанные на .Net, неожиданно сломались, когда кто-то перенес их на более новые операционные системы.

В конце концов, сделайте нормализацию всей информации о местной культуре инвариантной и неизменной и используйте ее в своей бизнес-логике в этом формате. Затем поместите его обратно на передний конец. То же самое относится и к DateTime, при первой возможности конвертируется в UTC и только обратно при рендеринге вывода.

0 голосов
/ 08 апреля 2011

Вы также можете попробовать класс Convert для выполнения этой задачи.

Convert.ToDecimal ("6.59");

...