双精度数据类型,小数位后的小数位数

时间:2011-09-08 10:11:35

标签: c#

下面的方法应该回答“小数精度,尾随数量的数量,这个(双重)值有多少?”。当值看起来像5900.43,5900.043等时,我做对了。当方法收到5900.00时,它返回0,这是错误的(在我需要的时候)。

   /// <summary>
   /// Return count of decimals after decimal-place 
   /// </summary>
   private int getDecimalCount(double val)
   {
        int count = 0;
        ...
        return count;
   }

当参数'val'为(此方法的正常值的样本)

5900.00返回2
5900.09返回2
5900.000返回3
5900.001返回3
1.0返回1
0.0000005返回7
1.0000000返回7
5900822返回0

我的问题是计算.0 .00 .000等等

问题:
我该如何解决这个问题?如果双方无法使用此方法,还有其他方法吗?

[EDITED]
- 进行小的文本更改以提出更明确的问题,
- 由于'小数位'的错误使用含义而导致的语言修正

4 个答案:

答案 0 :(得分:5)

编辑:已更新,以简化处理不同文化的过程。

与@Miguel类似,这是我将如何处理它:

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!");
    }
}

美国英语的快捷方法:

public static int getDecimalCount(double dVal, string sVal)
{
    return getDecimalCount(dVal, sVal, "en-US");
}

测试:

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();
}

最后,测试的输出:

  

使用dVal = 5900和sVal = 5900.00进行测试。   预期产出:2。实际产出:2

     

使用dVal = 5900.09和sVal = 5900.09进行测试。   预期产出:2。实际产出:2

     

使用dVal = 5900和sVal = 5900.000进行测试。   预期产出:3。实际产出:3

     

使用dVal = 5900.001和sVal = 5900.001进行测试。   预期产出:3。实际产出:3

     

使用dVal = 1和sVal = 1.0进行测试。   预期输出:1。实际输出:1

     

使用dVal = 5E-07和sVal = 0.0000005进行测试。   预期产出:7。实际产出:7

     

使用dVal = 1和sVal = 1.0000000进行测试。   预期产出:7。实际产出:7

     

使用dVal = 5900822和sVal = 5900822进行测试。   预期输出:0。实际输出:0

如果您对此有疑问或者没有意义,请告诉我。

答案 1 :(得分:2)

您正在考虑双精度的字符串表示形式。例如,双重不会产生差异:

123
123.0
123.000000

这就是所有相同的双倍,你得到多少小数位,实际上取决于你的字符串格式选项(或默认设置)。您可以做的是将您的双打格式化为具有大量小数位的字符串,然后删除所有尾随零,然后计算小数位。

答案 2 :(得分:2)

创建一个接收字符串而不是double的方法:

    public int CountDecimalDigits(string value)
    {
        char[] possibleChars = "0123456789.".ToCharArray();
        int decimalPoints = 0;
        foreach (char ch in value)
        {
            if (Array.IndexOf(possibleChars, ch) < 0)
                throw new Exception();
            if (ch == '.') decimalPoints++;
        }
        if (decimalPoints > 1)
            throw new Exception();
        if (decimalPoints == 0) return 0;
        return value.Length - value.IndexOf('.') - 1;
    }

答案 3 :(得分:1)

这不是所要求的,但这正是我所需要的。也许它会帮助某人:

children