17

When I try to convert a string to float:

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

it throws an exception:

Unhandled Exception: System.FormatException: Input string was not in a correct f ormat.
at System.Number.ParseSingle(String value, NumberStyles options, NumberFormat Info numfmt)

When I try it like this:

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

It throws the same exception:

Unhandled Exception: System.FormatException: Input string was not in a correct f ormat.
at System.Number.ParseSingle(String value, NumberStyles options, NumberFormat Info numfmt)
at System.Convert.ToSingle(String value)

Can you explain why this happens?

1
  • Have you tried breaking the code down into separate lines and stepping through on the debugger? Commented Apr 8, 2011 at 9:13

7 Answers 7

49

The single argument Parse method uses the current culture to parse the string. If your current culture uses some other decimal separator, this will fail.

Try using the invariant culture:

float.Parse("6.59", CultureInfo.InvariantCulture)
Sign up to request clarification or add additional context in comments.

1 Comment

+1 for this useful tip, my code was working on my development environment but not in the production environment.
5

The problem here is your culture.

Either set the invariant culture like this:

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

or use the correct decimal separator for your culture

float.Parse("6,59")

I wonder why you are using a literal string. If you are having problems entering literal floats, you can use

Console.WriteLine(6.59f)

If you do it this way culture doesn't matter because the value is decided at compile time.

2 Comments

The UK is Europe too! (I assumed the literal string was the result of trying to find "the simplest code that reproduces the problem").
Blasted imperial units! Go Metric! (just kidding) I forgot that the UK still uses the imperial system :) But my point still stands, if he's going to put string literals into float.Parse he's doing it all wrong.
4

You are probably using a culture that uses the , as a decimal seperator.

You could try to Parse using the InvariantCulture:

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

Comments

3

Culture - specific things. What's your default culture? Some cultures use "," instead of ".". You can try this:

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

Comments

2

There could be problem with Locale/Culture. You need to set , instead of . for the decimal separator.

1 Comment

Portuguese is even worse. Here . is the digit group separator (aka thousands separator). Because of this float.Parse("6.59") does not fail, but the result is 659. This has wasted me a couple of hours in the past :(
2

I know everyone here has already given the reason for the problem experienced but perhaps somebody should just expand on why Invariant fixes it.

The CultureInfo class is used either directly or indirectly by classes that format, parse, or manipulate culture-specific data, such as String, DateTime, DateTimeOffset, and the numeric types to deal with the differences in the way different cultures write these types.

In case of the decimal type some cultures use a period(.) whilst others use a comma (,). By default when you are using the Conversion Libraries it will make use of your local culture (that is the country your OS to configured for).

By specifying Invariant you say that you expect thousand separators to be commas(,) and decimal deliminator to be a period(.) as it is in most cultures.

A big problem that sometimes happens is that these cultural conventions change from the OS point of view. For example the South African (ZA) culture info used to behave like the invariant culture. Microsoft changed this with Windows 8 where the decimal suddenly became a comma and the thousand separator a space.This resulted in many legacy systems written in .Net suddently breaking when one migrated them to newer operating systems.

In the end, deal normalize all local culture info to invariant and persist and deal with them in your business logic in this format. Then localize it back on the front end. Same goes for DateTime, as soon as possible convert to UTC, and only back when you render an output.

Comments

0

You could also try Convert class to perform this task.

Convert.ToDecimal("6.59");

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.