Best way to parse float?
Asked Answered
C

11

51

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?

Chasidychasing answered 29/9, 2008 at 7:23 Comment(1)
Willing to that as it seems everybody's doing it. I personally try to keep away from <3 char search terms. Think it's something that stuck with me from passed times when all searches had to be >3 chars. Also the # sign makes my spider sences tingle.Chasidychasing
P
28

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.

Periwig answered 29/9, 2008 at 7:31 Comment(0)
A
66

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);
Aegir answered 29/9, 2008 at 7:30 Comment(0)
P
28

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.

Periwig answered 29/9, 2008 at 7:31 Comment(0)
C
7

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);
Copperplate answered 29/9, 2008 at 7:28 Comment(1)
true, but isn't really related to the question.Chasidychasing
C
6

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.

Camisole answered 29/9, 2008 at 7:30 Comment(0)
L
4

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

Laceylach answered 29/9, 2008 at 7:26 Comment(0)
P
1

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

Palstave answered 29/9, 2008 at 7:29 Comment(0)
C
0

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

Circumstantiate answered 29/9, 2008 at 7:37 Comment(4)
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.Unless
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!Frequency
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.Circumstantiate
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..Chasidychasing
C
0

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

Chasidychasing answered 30/9, 2008 at 7:59 Comment(0)
D
0

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

Doubly answered 30/9, 2008 at 8:26 Comment(0)
I
0

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.

Input answered 19/3, 2021 at 7:20 Comment(0)
S
-1

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.

Swoon answered 30/9, 2008 at 8:24 Comment(3)
If you are going to mark down the accepted answer at least explain why you are marking it down...Levin
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.Swoon
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.Swoon

© 2022 - 2024 — McMap. All rights reserved.