If you get a format exception, it means that the culture in which your code is running does not use a character . for its decimal separator. There are a few things you can do:
- Change your global culture to one that uses a symbol
. as a decimal separator - Manually replace the symbol
. decimal separator. - Calling the overload of various analysis methods that accept an instance of
IFormatProvider
I believe that the third option will be the best. It allows you to specify which format the parse method expects. The CultureInfo class implements the IFormatProvider interface. In code, you expect a character . will be the decimal separator. This is true in several cultures, but your safest choice is probably InvariantCulture .
You can change your code 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 used to determine the decimal separator used when parsing a string in double or float .
I created a .NET Fiddle to show you that it works: https://dotnetfiddle.net/Z5HB4T
You can see that the decimal separator for a particular culture using the NumberDecimalSeparator property of the CultureInfo NumberFormat :
// 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;
Take a look at the action: https://dotnetfiddle.net/nSbYoP
Interestingly, the NumberFormat property is of type NumberFormatInfo , which also implements IFormatProvider ! This means that you can also pass an instance of NumberFormatInfo to the analysis methods. This allows you to create a complete format to your liking. Then we could use any decimal separator string. The following examples will change the decimal 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 you complete freedom in how you want analysis methods to interpret numbers.