EDIT: Updated to simplify handling different cultures.
Similarly to @Miguel, here's how I would handle it:
public static int getDecimalCount(double dVal, string sVal, string culture)
{
CultureInfo info = CultureInfo.GetCultureInfo(culture);
//Get the double value of the string representation, keeping culture in mind
double test = Convert.ToDouble(sVal, info);
//Get the decimal separator the specified culture
char[] sep = info.NumberFormat.NumberDecimalSeparator.ToCharArray();
//Check to see if the culture-adjusted string is equal to the double
if (dVal != test)
{
//The string conversion isn't correct, so throw an exception
throw new System.ArgumentException("dVal doesn't equal sVal for the specified culture");
}
//Split the string on the separator
string[] segments = sVal.Split(sep);
switch (segments.Length)
{
//Only one segment, so there was not fractional value - return 0
case 1:
return 0;
//Two segments, so return the length of the second segment
case 2:
return segments[1].Length;
//More than two segments means it's invalid, so throw an exception
default:
throw new Exception("Something bad happened!");
}
}
And a shortcut method for US English:
public static int getDecimalCount(double dVal, string sVal)
{
return getDecimalCount(dVal, sVal, "en-US");
}
Testing:
static void Main(string[] args)
{
int i = 0;
double d = 5900.00;
string s = "5900.00";
Console.WriteLine("Testing with dVal = {0} and sVal = {1}.", d, s);
i = getDecimalCount(d, s);
Console.WriteLine("Expected output: 2. Actual output: {0}", i);
Console.WriteLine();
d = 5900.09;
s = "5900.09";
Console.WriteLine("Testing with dVal = {0} and sVal = {1}.", d, s);
i = getDecimalCount(d, s);
Console.WriteLine("Expected output: 2. Actual output: {0}", i);
Console.WriteLine();
d = 5900.000;
s = "5900.000";
Console.WriteLine("Testing with dVal = {0} and sVal = {1}.", d, s);
i = getDecimalCount(d, s);
Console.WriteLine("Expected output: 3. Actual output: {0}", i);
Console.WriteLine();
d = 5900.001;
s = "5900.001";
Console.WriteLine("Testing with dVal = {0} and sVal = {1}.", d, s);
i = getDecimalCount(d, s);
Console.WriteLine("Expected output: 3. Actual output: {0}", i);
Console.WriteLine();
d = 1.0;
s = "1.0";
Console.WriteLine("Testing with dVal = {0} and sVal = {1}.", d, s);
i = getDecimalCount(d, s);
Console.WriteLine("Expected output: 1. Actual output: {0}", i);
Console.WriteLine();
d = 0.0000005;
s = "0.0000005";
Console.WriteLine("Testing with dVal = {0} and sVal = {1}.", d, s);
i = getDecimalCount(d, s);
Console.WriteLine("Expected output: 7. Actual output: {0}", i);
Console.WriteLine();
d = 1.0000000;
s = "1.0000000";
Console.WriteLine("Testing with dVal = {0} and sVal = {1}.", d, s);
i = getDecimalCount(d, s);
Console.WriteLine("Expected output: 7. Actual output: {0}", i);
Console.WriteLine();
d = 5900822;
s = "5900822";
Console.WriteLine("Testing with dVal = {0} and sVal = {1}.", d, s);
i = getDecimalCount(d, s);
Console.WriteLine("Expected output: 0. Actual output: {0}", i);
Console.ReadLine();
}
And finally, the output of the test:
Testing with dVal = 5900 and sVal = 5900.00.
Expected output: 2. Actual output: 2
Testing with dVal = 5900.09 and sVal = 5900.09.
Expected output: 2. Actual output: 2
Testing with dVal = 5900 and sVal = 5900.000.
Expected output: 3. Actual output: 3
Testing with dVal = 5900.001 and sVal = 5900.001.
Expected output: 3. Actual output: 3
Testing with dVal = 1 and sVal = 1.0.
Expected output: 1. Actual output: 1
Testing with dVal = 5E-07 and sVal = 0.0000005.
Expected output: 7. Actual output: 7
Testing with dVal = 1 and sVal = 1.0000000.
Expected output: 7. Actual output: 7
Testing with dVal = 5900822 and sVal = 5900822.
Expected output: 0. Actual output: 0
Let me know if you have questions about it or it doesn't make sense.