views:

4297

answers:

5

I guess this is a very easy question, but I wasn't able to find a question with Google or the MSDN examples.

I want to parse a string like "3.5" to a double. However,

double.Parse("3.5")

yields 35 and

double.Parse("3.5", System.Globalization.NumberStyles.AllowDecimalPoint)

(something I tried in my desperation ;) ) which compiles just fine blows up with a FormatException.

Now I'm in Germany, where a comma is used as a separator (so 3,5). It might have to do something with this, but I'm not sure.

How can I do that?

+19  A: 
double.Parse("3.5", CultureInfo.InvariantCulture)
Mehrdad Afshari
Beat me to it by a few seconds
ChrisF
I like to use the `XmlConvert` class ... do you have any ideas whether this is better, worse, and/or different than using `CultureInfo.InvariantCulture`?
ChrisW
Well, `XmlConvert` is not really intended to be used to parse a single double value in code. I prefer to use `double.Parse` or `Convert.ToDouble` that make my intention obvious.
Mehrdad Afshari
This means doulble.Parse uses the default culture which may not contain dot as a decimal point??
Ahmed Said
It uses the current culture of the thread it's running on.
Mehrdad Afshari
this does not work in all kind of combinations. 1.234.567,89 e.g
JanW
+1  A: 

The trick is to use invariant culture, to parse dot in all cultures.

double.Parse("3.5", System.Globalization.NumberStyles.AllowDecimalPoint, System.Globalization.NumberFormatInfo.InvariantInfo);
Yakeen
Does not work in all scenarios. 1.234.567,89
JanW
+5  A: 

I usualy use a multi-culture function to parse user input, mostly because if someone is used to the numpad and is using a culture that use a comma as the decimal separator, that person will use the point of the numpad instead of a comma.

public static double GetDouble(string value, double defaultValue)
{
    double result;

    //Try parsing in the current culture
    if (!double.TryParse(value, System.Globalization.NumberStyles.Any, CultureInfo.CurrentCulture, out result) &&
        //Then try in US english
        !double.TryParse(value, System.Globalization.NumberStyles.Any, CultureInfo.GetCultureInfo("en-US"), out result) &&
        //Then in neutral language
        !double.TryParse(value, System.Globalization.NumberStyles.Any, CultureInfo.InvariantCulture, out result))
    {
        result = defaultValue;
    }

    return result;
}
Pierre-Alain Vigeant
I'm not sure that's a good idea. You can't reliably parse a double if you don't know the culture: In Germany, double values may contain '.'s, but they're considered to be thousands-separators there. So in Legate's case, GetDouble("3.5") would return 35 in a German locale and 3.5 in a en-us environment.
nikie
A: 
Double.Parse("3,5".Replace(',', '.'), CultureInfo.InvariantCulture)

Replace the comma with a point before parsing. Useful in countries with a comma as decimal separator. Think about limiting user input (if necessary) to one comma or point.

Baluda
A: 

This does the job in any scenario. Its a little bit parsing.

List<string> inputs = new List<string>()
{
    "1.234.567,89",
    "1 234 567,89",
    "1 234 567.89",
    "1,234,567.89",
    "123456789",
    "1234567,89",
    "1234567.89",
};
string output;

foreach (string input in inputs)
{
    // unify string (no spaces, only . )
    output = input.Trim().Replace(" ", "").Replace(",", ".");

    // split it on points
    string[] split = output.Split('.');

    if (split.Count() > 1)
    {
        // take all parts except last
        output = string.Join("", split.Take(split.Count()-1).ToArray());

        // combine token parts with last part
        output = string.Format("{0}.{1}", output, split.Last());
    }

    // parse double invariant
    double d = double.Parse(output, CultureInfo.InvariantCulture);
    Console.WriteLine(d);
}
JanW