更有效的方法来防止数字字符串值降低其小数精度

时间:2012-08-14 13:04:04

标签: c# .net performance

我有一个程序,它输出从第三方应用程序接收的字符串值列表。

已经发出请求,要求最终用户希望将所有小数精度级别保持在设置的最高级别。由于每个新值都会覆盖最后一个值,因此无需向后应用此值,只需转发。

因此,如果它达到3级精度,那么它应该保持在该级别。 例如。如果收到的值是:1,15,15.2,4.25,1.111,3.4,1那么输出将是:

1,15,15.2,4.25,1.111,3.400,1.000

我已经编写了以下代码来完成这项工作,但对我来说这似乎并不优雅。性能在这里也非常重要,因为可能会有100个样本出现,所以这不会影响性能。事实上,如果确定这会导致应用程序显着减速,那么该要求可能会被删除。

    int numberOfDecimals = 0;

    private string FormatValueToMinimumNumberOfDecimals(string value)
    {            
            decimal doubleValue;                

            if (decimal.TryParse(value, out doubleValue))
            {
                int numberOfDecimals = this.CountDecimalPlace(doubleValue);
                if (this.numberOfDecimals > numberOfDecimals)
                {
                    value = doubleValue.ToString(String.Format("N{0}", this.numberOfDecimals.ToString()));
                }
                else
                {
                    this.numberOfDecimals = numberOfDecimals;
                }
            }

        return value;
    }

    private int CountDecimalPlace(decimal val)
    {
        int decimalCount = 0;
        decimal ten = 10;
        while (val != Math.Floor(val))
        {
            val *= ten;
            decimalCount++;
        }
        return decimalCount;
    }

所以问题是,任何人都可以想到更好/更快的方式吗?

此外,如果提供的工作解决方案存在任何明显问题,请随意指出它们。

1 个答案:

答案 0 :(得分:3)

要从字符串中获取小数位数,请使用IndexOf

var sep = NumberFormatInfo.CurrentInfo.CurrencyDecimalSeparator; 
var pos = val.IndexOf(sep); 
var pre = (pos == -1) ? 0 : val.Length - pos - 1; 

要从小数类型中获取精度,请使用Decimal.GetBits

var pre = (Decimal.GetBits(val)[3] >> 16) & 0x000000FF; 

此外,您可以使用NumberFormatInfo而不是String.Format()

NumberFormatInfo nfi = new NumberFormatInfo();
nfi.NumberDecimalDigits = this.numberOfDecimals;
value = doubleValue.ToString("N", nfi);