2009-07-15 119 views
57

在C#中这些线调整小数精度,.NET

decimal a = 2m; 
decimal b = 2.0m; 
decimal c = 2.00000000m; 
decimal d = 2.000000000000000000000000000m; 

Console.WriteLine(a); 
Console.WriteLine(b); 
Console.WriteLine(c); 
Console.WriteLine(d); 

生成的输出:

2 
2.0 
2.00000000 
2.000000000000000000000000000 

所以我可以看到,创建从文字小数变量可以让我来控制的精度。

  • 我可以在不使用文字的情况下调整小数变量的精度吗?
  • 如何从a创建b?我怎样才能从c创建b?

回答

44

保留像这样的尾随零是在.NET 1.1中引入的,用于更严格地符合ECMA CLI规范。

在MSDN上有这方面的信息,例如: here

可以按如下方式调整精度:

  • Math.Round(或天花板,地板等)由1.000下降精密(B c)从

  • 乘...(用你想要的小数位数)来提高精度 - 例如乘以1.0M从a得到b。

17

您只会看到完全相同数据的不同表示。 decimal的精确度将被缩放为与需要的一样大(在合理范围内)。

System.Decimal

的十进制数是一个浮点 值,它由一个符号,一个 数字值,其中在 值的每个数字范围从0到9的,和一个 比例因子,表示浮点小数点 的 位置,该位置将积分和 数字值的小数部分分开。

一个十进制 值的二进制表示由一个1位的符号,一个 96位整数,用来划分96位 整数,并指定其什么部分的缩放 因子 是一个小数部分。缩放因子 是隐式地升高到一个指数取值范围为0到 28.因此,10号, ,一个十进制值的二进制 表示是所述形式,((-2 到的 )/ 10 (0至 28)),其中-2 -1等于 MINVALUE,和2 -1等于 MaxValue的。

缩放因子还保留任何 十进制数中的尾随零。 尾数零不会影响算术或比较操作中的一个十进制数的 值。 但是,如果应用了 适当的格式字符串,则尾部零可以是由ToString方法显示的 。

+1

有关比例因子的好信息...现在我该如何调整它? – 2009-07-15 17:33:14

+1

缩放因子不可直接控制,因为它根据指数的大小进行调整。这基本上是浮点运算(以及术语“浮动”来自何处)的原理。由于有效位的位数是常数,因此数的大小决定了有效位的位数。 – codekaizen 2009-07-15 17:57:07

+0

它会自动调整以适应其包含的数据需求。是否有一个特定的原因需要手动缩放它? – 2009-07-15 17:58:37

1

问题是 - 你是否真的需要精度为存储在在十进制,而不是只显示小数到所需的精度。 大多数应用程序内部知道他们想要的精度和显示精度。例如,即使用户在帐户包中输入100的发票,它仍然会使用类似val.ToString(“n2”)的值打印为100.00。

如何从a创建b?我怎样才能从c创建b?

c to b is possible。

Console.WriteLine(Math.Round(2.00000000m, 1)) 

产生2.0

a到b是棘手,因为引入精度的概念是一个小外星人数学。

我想一个可怕的黑客可能是一次往返。

decimal b = Decimal.Parse(a.ToString("#.0")); 
Console.WriteLine(b); 

产生2.0

5

我发现我能“篡改”随着规模乘以或看上分割1.

decimal a = 2m; 
decimal c = 2.00000000m; 
decimal PreciseOne = 1.000000000000000000000000000000m; 
    //add maximum trailing zeros to a 
decimal x = a * PreciseOne; 
    //remove all trailing zeros from c 
decimal y = c/PreciseOne; 

我可以制造一个足够精确的1改变规模因素已知的大小。

decimal scaleFactorBase = 1.0m; 
decimal scaleFactor = 1m; 
int scaleFactorSize = 3; 

for (int i = 0; i < scaleFactorSize; i++) 
{ 
    scaleFactor *= scaleFactorBase; 
} 

decimal z = a * scaleFactor; 
5

人们很容易在.NET混淆decimal在SQL Server与decimal;他们完全不同。

SQL Server decimal是一个定点数,当定义列或变量时,其精度和比例是固定的。

甲.NET decimal是像floatdouble一个浮点数(不同之处在于decimal准确保留十进制数字而floatdouble准确保存二进制数)。试图控制.NET的精确度是毫无意义的,因为无论是否存在填充零,所有计算结果都会得到相同的结果。

-1

这将删除小数点后的所有尾随零,然后您可以使用ToString()

public static class DecimalExtensions 
{ 
    public static Decimal Normalize(this Decimal value) 
    { 
     return value/1.000000000000000000000000000000000m; 
    } 
} 

或者,如果你想尾随零的一个确切的数字,说5,第一规格化(),然后乘以1.00000米。