Method below should return a answer to "What decimal precision, quantity of trailing numbers, do this (double) value have?". I got it right when the values looks like 5900.43, 5900.043 and so on. When the method recieves 5900.00, it return 0, which is wrong (in my need).
/// <summary>
/// Return count of decimals after decimal-place
/// </summary>
private int getDecimalCount(double val)
{
int count = 0;
...
return count;
}
When parameter 'val' is (samples of normal values to this method)
5900.00 return 2
5900.09 return 2
5900.000 return 3
5900.001 return 3
1.0 return 1
0.0000005 return 7
1.0000000 return 7
5900822 return 0
My problem is counting .0 .00 .000 and so on
Question:
How do I solve this? If this method isn't possible with doubles, how else?
[EDITED]
- Minor text change to make a more clear question,
- Language correction due to miss-used meaning of 'decimal places'
double has 15 decimal digits of precision.
How many joule in 1 decimal? The answer is 1. Note that rounding errors may occur, so always check the results.
Double precision numbers are accurate up to sixteen decimal places but after calculations have been done there may be some rounding errors to account for.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With