77

I have a long string with double-type values separated by # -value1#value2#value3# etc

I splitted it to string table. Then, I want to convert every single element from this table to double type and I get an error. What is wrong with type-conversion here?

string a = "52.8725945#18.69872650000002#50.9028073#14.971600200000012#51.260062#15.5859949000000662452.23862099999999#19.372202799999250800000045#51.7808372#19.474096499999973#";
string[] someArray = a.Split(new char[] { '#' });
for (int i = 0; i < someArray.Length; i++)
{
    Console.WriteLine(someArray[i]); // correct value
    Convert.ToDouble(someArray[i]); // error
}
whoah
  • 4,013
  • 10
  • 47
  • 81
  • 6
    What error? It works fine for me... – Dave Bish Jul 09 '12 at 16:40
  • 3
    @DaveBish try looping through all of them, you'll see that index 5 is a bad string to convert to a double. – Stefan H Jul 09 '12 at 16:43
  • 2
    @StefanH: Of course, but index 0 appears to be good. –  Jul 09 '12 at 16:43
  • 1
    One of your input values has two decimal places. – Matt Jul 09 '12 at 16:44
  • Look at the bytes of the string `tablicaLatLng[0]`, that should show you what is wrong. – NominSim Jul 09 '12 at 16:46
  • If the strings don't meet the formats and bounds described on MSDN then they won't be convertible, I suggest reading MSDN. http://msdn.microsoft.com/en-us/library/zh1hkw6k.aspx. What exceptions do you get, that will be the clue. – Jodrell Jul 09 '12 at 16:51
  • I have compiled your code and I do not have any problems building it. What error are you getting? Is this all the code? –  Jul 09 '12 at 16:51
  • I am voting to close as too localized. This seems like an issue no one can provide a suitable answer for at the moment and it is simply frustrating folks. –  Jul 09 '12 at 17:02
  • @0A0D check my answer, it should fix this problem – Zbigniew Jul 09 '12 at 17:05
  • @Ramhound If it is any consolation it looks as though you were wrong (we both were). The issue was in fact someone trying to parse values from one culture into another. The OP's question had some red herrings in it, but we both made assumptions about what the issue was (due to some bad info on the OP's part) that lead us down the wrong path. – Stefan H Jul 09 '12 at 17:10
  • Perhaps this should not be closed. It is not "only relevant to a small geographic area". It is always a bug to use a locale-dependent function for a locale-independent problem; it's a very common bug. And it's as much a bug in Kansas as in Munich. Only in Kansas it's harder to find. (BTW: I found this question because I had exactly this bug in my code, do I count as a future visitor?) – Adrian Ratnapala May 09 '13 at 14:16

6 Answers6

185

There are 3 problems.

1) Incorrect decimal separator

Different cultures use different decimal separators (namely , and .).

If you replace . with , it should work as expected:

Console.WriteLine(Convert.ToDouble("52,8725945"));

You can parse your doubles using overloaded method which takes culture as a second parameter. In this case you can use InvariantCulture (What is the invariant culture) e.g. using double.Parse:

double.Parse("52.8725945", System.Globalization.CultureInfo.InvariantCulture);

You should also take a look at double.TryParse, you can use it with many options and it is especially useful to check wheter or not your string is a valid double.

2) You have an incorrect double

One of your values is incorrect, because it contains two dots:

15.5859949000000662452.23862099999999

3) Your array has an empty value at the end, which is an incorrect double

You can use overloaded Split which removes empty values:

string[] someArray = a.Split(new char[] { '#' }, StringSplitOptions.RemoveEmptyEntries);

Zbigniew
  • 25,495
  • 6
  • 53
  • 63
  • 1
    Thanks for the downvotes and explanations. I have accually tried to convert version with `.` and it gave me `StringFormatException`, when I changed it to `,` it worked (culture: pl_PL). This is also answer for his question (regarding first *double*). – Zbigniew Jul 09 '12 at 16:48
  • yea, replacing `.` with `,` works fine but I have to get a values with `.`, not with `,` (for google api - lat and lng requires '.'). – whoah Jul 09 '12 at 16:56
  • +1 good catch. Can you tell @whoah how to "change culture" for parsing? Or parse in a different culture? – Rob I Jul 09 '12 at 17:00
  • @Robl sure thing, it has happend to me once so it was first thing in my mind :P – Zbigniew Jul 09 '12 at 17:02
  • 1
    great ! this works perfect :) could you tell me, what means this part? `System.Globalization.CultureInfo.InvariantCulture`? Big thanks for help, greetings! – whoah Jul 09 '12 at 17:10
  • @whoah Read this: [InvariantCulture](http://msdn.microsoft.com/en-us/library/system.globalization.cultureinfo.invariantculture.aspx) and this: [What is the Invariant Culture?](http://stackoverflow.com/questions/2423377/what-is-the-invariant-culture) – Zbigniew Jul 09 '12 at 17:12
  • @des - wow, great, now understand :) thanks for help! and one simply question - why my first post get "-1"? What is wrong? I think that problem presented in question wasn't so stupid :p – whoah Jul 09 '12 at 17:17
  • @whoah I don't think the question was stupid, but rather due to the other issues in your question, there were a few red herrings which made it difficult to determine what your actual problem was. – Stefan H Jul 09 '12 at 19:57
  • @Zbigniew Downvotes you say? Here an upvote. Thanks. Solved my problem. – Syaiful Nizam Yahya Jan 26 '18 at 02:49
  • @SyaifulNizamYahya old times, right now this answer has +90/-1 :P Thanks for the upvote though. Because of all the upvotes I decided to edit and expand my answer. – Zbigniew Jan 27 '18 at 16:58
9

Add a class as Public and use it very easily like convertToInt32()

  using System;
  using System.Collections.Generic;
  using System.Linq;
  using System.Web;

  /// <summary>
  /// Summary description for Common
  /// </summary>
  public static class Common
  {
     public static double ConvertToDouble(string Value) {
        if (Value == null) {
           return 0;
        }
        else {
           double OutVal;
           double.TryParse(Value, out OutVal);

           if (double.IsNaN(OutVal) || double.IsInfinity(OutVal)) {
              return 0;
           }
           return OutVal;
        }
     }
  }

Then Call The Function

double DirectExpense =  Common.ConvertToDouble(dr["DrAmount"].ToString());
Arun Prasad E S
  • 7,342
  • 6
  • 61
  • 75
7

Most people already tried to answer your questions.
If you are still debugging, have you thought about using:

Double.TryParse(String, Double);

This will help you in determining what is wrong in each of the string first before you do the actual parsing.
If you have a culture-related problem, you might consider using:

Double.TryParse(String, NumberStyles, IFormatProvider, Double);

This http://msdn.microsoft.com/en-us/library/system.double.tryparse.aspx has a really good example on how to use them.

If you need a long, Int64.TryParse is also available: http://msdn.microsoft.com/en-us/library/system.int64.tryparse.aspx

Hope that helps.

Ervi B
  • 582
  • 5
  • 15
4
private double ConvertToDouble(string s)
    {
        char systemSeparator = Thread.CurrentThread.CurrentCulture.NumberFormat.CurrencyDecimalSeparator[0];
        double result = 0;
        try
        {
            if (s != null)
                if (!s.Contains(","))
                    result = double.Parse(s, CultureInfo.InvariantCulture);
                else
                    result = Convert.ToDouble(s.Replace(".", systemSeparator.ToString()).Replace(",", systemSeparator.ToString()));
        }
        catch (Exception e)
        {
            try
            {
                result = Convert.ToDouble(s);
            }
            catch
            {
                try
                {
                    result = Convert.ToDouble(s.Replace(",", ";").Replace(".", ",").Replace(";", "."));
                }
                catch {
                    throw new Exception("Wrong string-to-double format");
                }
            }
        }
        return result;
    }

and successfully passed tests are:

        Debug.Assert(ConvertToDouble("1.000.007") == 1000007.00);
        Debug.Assert(ConvertToDouble("1.000.007,00") == 1000007.00);
        Debug.Assert(ConvertToDouble("1.000,07") == 1000.07);
        Debug.Assert(ConvertToDouble("1,000,007") == 1000007.00);
        Debug.Assert(ConvertToDouble("1,000,000.07") == 1000000.07);
        Debug.Assert(ConvertToDouble("1,007") == 1.007);
        Debug.Assert(ConvertToDouble("1.07") == 1.07);
        Debug.Assert(ConvertToDouble("1.007") == 1007.00);
        Debug.Assert(ConvertToDouble("1.000.007E-08") == 0.07);
        Debug.Assert(ConvertToDouble("1,000,007E-08") == 0.07);
bask0xff
  • 112
  • 2
  • 11
1

You can try this example out. A simple C# progaram to convert string to double

class Calculations{

protected double length;
protected double height;
protected double width;

public void get_data(){

this.length = Convert.ToDouble(Console.ReadLine());
this.width  = Convert.ToDouble(Console.ReadLine());
this.height = Convert.ToDouble(Console.ReadLine());

   }
}
0

In your string I see: 15.5859949000000662452.23862099999999 which is not a double (it has two decimal points). Perhaps it's just a legitimate input error?

You may also want to figure out if your last String will be empty, and account for that situation.

Rob I
  • 5,180
  • 2
  • 18
  • 28