7

I need to convert a string to double. Or float, whatever suits best for this type of conversion.

The string is "25.00".

How would I convert this string so that I can use it in calculations?

I've tried with:

string s1 = "2";
string s2 = "25.00";

double d1 = Convert.ToDouble(s1);
double d2 = Convert.ToDouble(s2);
double d3 = d2 * d1;

I've also tried with this:

string s1 = "2";
string s2 = "25.00";

double d1 = double.Parse(s1);
double d2 = double.Parse(s2);
double d3 = d2 * d1;

And:

string s1 = "2";
string s2 = "25.00";

float f1 = float.Parse(s1);
float f2 = float.Parse(s2);
float f3 = f2 * f1;

None of this seem to work, I get a formatexception.

Kim Andersson
  • 251
  • 2
  • 4
  • 15

3 Answers3

7

I suspect your default culture info uses comma as a decimal separator instead of dot. If you know your input will have a dot, it's best to specify the invariant culture explicitly:

double d1 = double.Parse(s1, CultureInfo.InvariantCulture);
double d2 = double.Parse(s2, CultureInfo.InvariantCulture);

However, if the decimal values matter, you should consider using decimal instead of either float or double:

decimal d1 = decimal.Parse(s1, CultureInfo.InvariantCulture);
decimal d2 = decimal.Parse(s2, CultureInfo.InvariantCulture);
Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
4

If you get a format exception, that means that the culture you are running your code on does not use the . character for its decimal separator. There are several things you can do:

  1. Change your global culture to one that uses the . character as its decimal separator
  2. Manually replace the . character with your culture's decimal separator
  3. Call an overload of the various parse methods that takes in an IFormatProvider instance

I consider the third option to be the best by far. It lets you specify what format the parse method expects. The CultureInfo class implements the IFormatProvider interface. In your code, you expect the . character to be the decimal separator. This is true in several cultures, but your safest choice is probably the InvariantCulture.

You can modify your code then as follows:

string s1 = "2"; 
string s2 = "25.00";

double d1 = Convert.ToDouble(s1, CultureInfo.InvariantCulture);
double d2 = Convert.ToDouble(s2, CultureInfo.InvariantCulture);
double d3 = d2 * d1;
string s1 = "2";
string s2 = "25.00";

double d1 = double.Parse(s1, CultureInfo.InvariantCulture);
double d2 = double.Parse(s2, CultureInfo.InvariantCulture);
double d3 = d2 * d1;
string s1 = "2";
string s2 = "25.00";

float f1 = float.Parse(s1, CultureInfo.InvariantCulture);
float f2 = float.Parse(s2, CultureInfo.InvariantCulture);
float f3 = f2 * f1;

Here, the CultureInfo class' NumberFormat property is used to determine the decimal separator used when parsing the string to a double or float.

I have created a .NET Fiddle to show you that it works: https://dotnetfiddle.net/Z5HB4T

You can see what the decimal separator is for a specific culture by using the NumberDecimalSeparator property of the CultureInfo's NumberFormat property:

// Returns: "."
CultureInfo.InvariantCulture.NumberFormat.NumberDecimalSeparator;

// Outputs: "."
new CultureInfo("en-US").NumberFormat.NumberDecimalSeparator;

// Returns: ","
new CultureInfo("nl-NL").NumberFormat.NumberDecimalSeparator;

// Returns: "<depends on what is set as the current culture>"
CultureInfo.CurrentCulture.NumberFormat.NumberDecimalSeparator;

See it in action at: https://dotnetfiddle.net/nSbYoP

What is interesting, is that the NumberFormat property is of type NumberFormatInfo which also implements IFormatProvider! This means that you could also pass a NumberFormatInfo instance to the parse methods. This allows you to create a number format fully to your liking. We could then use any decimal number separator string we like. The following examples changes the decimal number separator to the # character:

var numberFormatInfo = new NumberFormatInfo();
numberFormatInfo.NumberDecimalSeparator = "#";

string s1 = "2"; 
string s2 = "25#00";

double d1 = Convert.ToDouble(s1, numberFormatInfo);
double d2 = Convert.ToDouble(s2, numberFormatInfo);
double d3 = d2 * d1;

See: https://dotnetfiddle.net/h6ex2Z

This approach gives your total freedom on how you want the parse methods to interpret numbers.

Erik Schierboom
  • 16,301
  • 10
  • 64
  • 81
0

sometimes when you convert for example the string "4.1" to double the conversion will gives you 41, for that you can easy fix replacing the "." with "," ej: double ress = Convert.toDouble("4.1".replace(".",",");