views:

5291

answers:

10

What is the best way to parse a float in CSharp? I know about TryParse, but what I'm particularly wondering about is dots, commas etc.

I'm having problems with my website. On my dev server, the ',' is for decimals, the '.' for separator. On the prod server though, it is the other way round. How can I best capture this?

A: 

Use a neutral culture (or one you know) when parsing with Try/Parse.

leppie
+1  A: 

If you want persist values ( numbers, date, time, etc... ) for internal purpose. Everytime use "InvariantCulture" for formating & parsing values. "InvariantCulture" is same on every computer, every OS with any user's culture/language/etc...

string strFloat = (15.789f).ToString( System.Globalization.CultureInfo.InvariantInfo );
float numFloat = float.Parse( System.Globalization.CultureInfo.InvariantInfo, strFloat );
string strNow = DateTime.Now.ToString( System.Globalization.CultureInfo.InvariantInfo );
DateTime now = DateTime.Parse( System.Globalization.CultureInfo.InvariantInfo, strNow );
TcKs
true, but isn't really related to the question.
borisCallens
+1  A: 

Pass in a CultureInfo or NumberFormatInfo that represents the culture you want to parse the float as; this controls what characters are used for decimals, group separators, etc.

For example to ensure that the '.' character was treated as the decimal indicator you could pass in CultureInfo.InvariantCulture (this one is typically very useful in server applications where you tend to want things to be the same irrespective of the environment's culture).

Greg Beech
+6  A: 

I agree with leppie's reply; to put that in terms of code:

        string s = "123,456.789";
        float f = float.Parse(s, CultureInfo.InvariantCulture);
Marc Gravell
+2  A: 

you could always use the overload of Parse which includes the culture to use?

for instance:

Double number = Double.Parse("42,22", new CultureInfo("nl-NL").NumberFormat); // dutch number formatting

If you have control over all your data, you should use "CultureInfo.InvariantCulture" in all of your code.

Davy Landman
+9  A: 

Depends where the input is coming from.

If your input comes from the user, you should use the CultureInfo the user/page is using (Thread.CurrentThread.CurrentUICulture).

You can get and indication of the culture of the user, by looking at the HttpRequest.UserLanguages property. (Not correct 100%, but I've found it a very good first guess) With that information, you can set the Thread.CurrentThread.CurrentUICulture at the start of the page.

If your input comes from an internal source, you can use the InvariantCulture to parse the string.

The Parse method is somewhat easier to use, if your input is from a controlled source. That is, you have already validated the string. Parse throws a (slow) exception if its fails.

If the input is uncontrolled, (from the user, or other Internet source) the TryParse looks better to me.

GvS
A: 

Try to avoid float.Parse, use TryParse instead as it performs a lot better but does the same job. this also applies to double, DateTime, etc...

(some types also offer TryParseExact which also performs even better!)

Joachim Kerschbaumer
Does TryParse really work faster even when all the data is valid? I would expect them to have the same performance in the "success" case, but for failure to be faster with TryParse than Parse due to the cost of throwing exceptions.
Jon Skeet
And then again, what if TryParse returns false -- are you going to throw an exception? In that case float.Parse is more efficient than TryParse!
Sklivvz
if the strings you parse are mostly valid floats, tryparse is definitely faster. if you have lots of different strings maybe parse is the better choice, but when getting lots of strings (dozens of thousands) that are all (in 99% of the cases) valid floats in string representation, use tryparse.
Joachim Kerschbaumer
Are you sure you don't mean the other way round? I would guesstimate that Parse is only usefull with lots of correct floats and TryParse has some overhead that pays only when there is a larger chance the string is invalid..
borisCallens
A: 

The source is an input from a website. I can't rely on it being valid. So I went with TryParse as mentioned before. But I can't figure out how to give the currentCulture to it.

Also, this would give me the culture of the server it's currently running on, but since it's the world wide web, the user can be from anywhere...

borisCallens
A: 

Since you don't know the web user's culture, you can do some guesswork. TryParse with a culture that uses , for separators and . for decimal, AND TryParse with a culture that uses . for separators and , for decimal. If they both succeed but yield different answers then you'll have to ask the user which they intended. Otherwise you can proceed normally, given your two equal results or one usable result or no usable result.

Windows programmer
If you are going to mark down the accepted answer at least explain why you are marking it down...
Omar Kooheji
This answer was marked down before being accepted. Actually I'm a bit surprised to see this was accepted, since someone else suggested looking at the HttpRequest.UserLanguages property. I think my answer should be in second place though.
Windows programmer
Oh, now it's been marked down a second time after being accepted. I agree with that suggestion now, whoever marked it down after acceptance should at least explain why.
Windows programmer
A: 

Hello, you can know current Cuklture of your server with a simple statement: System.Globalization.CultureInfo culture = System.Globalization.CultureInfo.CurrentCulture;

Note that there id a CurrentUICulture property, but UICulture is used from ResourceMeanager form multilanguages applications. for number formatting, you must considere CurrentCulture.

i hope i help you

stefano m