How do I parse a string with a decimal point to a double?

前端 未结 19 1285
孤街浪徒
孤街浪徒 2020-11-22 06:47

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

double.Parse(\"3.5\") 

yields 35 and

double.Pars         


        
相关标签:
19条回答
  • 2020-11-22 07:02

    Instead of having to specify a locale in all parses, I prefer to set an application wide locale, although if string formats are not consistent across the app, this might not work.

    CultureInfo.DefaultThreadCurrentCulture = new CultureInfo("pt-PT");
    CultureInfo.DefaultThreadCurrentUICulture = new CultureInfo("pt-PT");
    

    Defining this at the begining of your application will make all double parses expect a comma as the decimal delimiter. You can set an appropriate locale so that the decimal and thousands separator fits the strings you are parsing.

    0 讨论(0)
  • 2020-11-22 07:03

    I improved the code of @JanW as well...

    I need it to format results from medical instruments, and they also send ">1000", "23.3e02", "350E-02", and "NEGATIVE".

    private string FormatResult(string vResult)
    {
      string output;
      string input = vResult;
    
      // 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());
      }
      string sfirst = output.Substring(0, 1);
    
      try
      {
        if (sfirst == "<" || sfirst == ">")
        {
          output = output.Replace(sfirst, "");
          double res = Double.Parse(output);
          return String.Format("{1}{0:0.####}", res, sfirst);
        }
        else
        {
          double res = Double.Parse(output);
          return String.Format("{0:0.####}", res);
        }
      }
      catch
      {
        return output;
      }
    }
    
    0 讨论(0)
  • 2020-11-22 07:03

    I think it is the best answer:

    public static double StringToDouble(string toDouble)
    {
        toDouble = toDouble.Replace(",", "."); //Replace every comma with dot
    
        //Count dots in toDouble, and if there is more than one dot, throw an exception.
        //Value such as "123.123.123" can't be converted to double
        int dotCount = 0;
        foreach (char c in toDouble) if (c == '.') dotCount++; //Increments dotCount for each dot in toDouble
        if (dotCount > 1) throw new Exception(); //If in toDouble is more than one dot, it means that toCount is not a double
    
        string left = toDouble.Split('.')[0]; //Everything before the dot
        string right = toDouble.Split('.')[1]; //Everything after the dot
    
        int iLeft = int.Parse(left); //Convert strings to ints
        int iRight = int.Parse(right);
    
        //We must use Math.Pow() instead of ^
        double d = iLeft + (iRight * Math.Pow(10, -(right.Length)));
        return d;
    }
    
    0 讨论(0)
  • 2020-11-22 07:04
    double.Parse("3.5", CultureInfo.InvariantCulture)
    
    0 讨论(0)
  • 2020-11-22 07:04

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

    Beware though, @nikie comments are true. To my defense, I use this function in a controlled environment where I know that the culture can either be en-US, en-CA or fr-CA. I use this function because in French, we use the comma as a decimal separator, but anybody who ever worked in finance will always use the decimal separator on the numpad, but this is a point, not a comma. So even in the fr-CA culture, I need to parse number that will have a point as the decimal separator.

    0 讨论(0)
  • 2020-11-22 07:04

    I couldn't write a comment, so I write here:

    double.Parse("3.5", CultureInfo.InvariantCulture) is not a good idea, because in Canada we write 3,5 instead of 3.5 and this function gives us 35 as a result.

    I tested both on my computer:

    double.Parse("3.5", CultureInfo.InvariantCulture) --> 3.5 OK
    double.Parse("3,5", CultureInfo.InvariantCulture) --> 35 not OK
    

    This is a correct way that Pierre-Alain Vigeant mentioned

    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;
    }
    
    0 讨论(0)
提交回复
热议问题