确定输入数字的小数精度

时间:2010-07-19 14:17:21

标签: c# decimal precision decimal-point

我们有一个有趣的问题,我们需要确定用户输入(文本框)的小数精度。基本上我们需要知道输入的小数位数,然后返回一个精确数字,最好用例子说明:

输入的<4500>将产生结果1
输入4500.1将产生结果0.1
输入4500.00将产生结果0.01
输入4500.450将得到0.001

的结果

我们正在考虑使用字符串,找到小数点分隔符,然后计算结果。只是想知道是否有更简单的解决方案。

7 个答案:

答案 0 :(得分:15)

我认为你应该按照你的建议 - 使用小数点的位置。明显的缺点可能是你必须自己考虑国际化。

var decimalSeparator = NumberFormatInfo.CurrentInfo.CurrencyDecimalSeparator;

var position = input.IndexOf(decimalSeparator);

var precision = (position == -1) ? 0 : input.Length - position - 1;

// This may be quite unprecise.
var result = Math.Pow(0.1, precision);

您可以尝试另一种方法 - Decimal类型存储内部精度值。因此,您可以使用Decimal.TryParse()并检查返回的值。也许解析算法保持输入的精度。

最后我建议不要使用浮点数来尝试。只是解析输入将删除有关尾随零的任何信息。所以你必须添加一个人工非零数字来保存它们或做类似的技巧。您可能会遇到精确问题。最后,基于浮点数找到精度也不简单。我看到一些丑陋的数学或一个循环乘以每次迭代十次,直到不再有任何小数部分。循环带来了新的精度问题......

<强>更新

解析成十进制的作品。有关详细信息,请Decimal.GetBits()

var input = "123.4560";

var number = Decimal.Parse(input);

// Will be 4.
var precision = (Decimal.GetBits(number)[3] >> 16) & 0x000000FF;

从这里使用Math.Pow(0.1, precision)是直截了当的。

答案 1 :(得分:11)

  

只是想知道是否有一个更容易   解决这个问题。

没有

使用字符串:

string[] res = inputstring.Split('.');
int precision = res[1].Length;

答案 2 :(得分:8)

由于您的上一个示例表明尾随零是重要的,我将排除任何数值解决方案并进行字符串操作。

答案 3 :(得分:3)

不,没有更简单的解决方案,你必须检查字符串。如果您将"4500""4500.00"转换为数字,它们都会变为值4500,因此您无法确定小数点分隔符后面有多少个非数字位数。

答案 4 :(得分:2)

另外,Decimal试图保持用户输入的精度。例如,

Console.WriteLine(5.0m);
Console.WriteLine(5.00m);
Console.WriteLine(Decimal.Parse("5.0"));
Console.WriteLine(Decimal.Parse("5.00"));

输出:

5.0
5.00
5.0
5.00

如果你追踪输入精度的动机纯粹是出于输入和输出的原因,这可能足以解决你的问题。

答案 5 :(得分:1)

使用字符串很简单。

如果没有“。”在字符串中,返回1。

否则返回“0”,后跟n-1“0”,后跟一个“1”,其中n是小数点后的字符串长度。

答案 6 :(得分:1)

这是使用字符串的可能解决方案;

static double GetPrecision(string s)
{ 
    string[] splitNumber = s.Split('.');
    if (splitNumber.Length > 1)
    {
        return 1 / Math.Pow(10, splitNumber[1].Length);
    }
    else
    {
        return 1;
    }
}

这里有一个问题; Calculate System.Decimal Precision and Scale看起来如果你想深入研究它可能会引起人们的兴趣。