Boris Callens
Boris Callens

Reputation: 93327

Best way to parse float?

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?

Upvotes: 51

Views: 122223

Answers (11)

TarmoPikaro
TarmoPikaro

Reputation: 5233

One approach is to force localization to use dot instead of comma separator - this way your code will work identically on all windows machines independently from selected language and settings.

This approach is applicable to small gained applications, like test applications, console applications and so on. For application, which was localization in use this is not so useful, but depends on requirements of application.

var CurrentCultureInfo = new CultureInfo("en", false);
CurrentCultureInfo.NumberFormat.NumberDecimalSeparator = ".";
CurrentCultureInfo.NumberFormat.CurrencyDecimalSeparator = ".";
Thread.CurrentThread.CurrentUICulture = CurrentCultureInfo;
Thread.CurrentThread.CurrentCulture = CurrentCultureInfo;
CultureInfo.DefaultThreadCurrentCulture = CurrentCultureInfo;

This code forces to use dot ('.') instead of comma, needs to be placed at application startup.

Upvotes: 0

TcKs
TcKs

Reputation: 26632

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);

Upvotes: 7

Davy Landman
Davy Landman

Reputation: 15439

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.

Upvotes: 6

Marc Gravell
Marc Gravell

Reputation: 1062780

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);

Upvotes: 66

stefano m
stefano m

Reputation: 4224

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 this will help you

Upvotes: 0

GvS
GvS

Reputation: 52518

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.

Upvotes: 28

Windows programmer
Windows programmer

Reputation: 8065

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.

Upvotes: -1

Boris Callens
Boris Callens

Reputation: 93327

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...

Upvotes: 0

Joachim Kerschbaumer
Joachim Kerschbaumer

Reputation: 9871

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!)

Upvotes: 0

Greg Beech
Greg Beech

Reputation: 136617

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).

Upvotes: 1

leppie
leppie

Reputation: 117230

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

Upvotes: 4

Related Questions