为什么C#十进制系统会记住尾随的零?

为什么C#十进制系统会记住尾随的零?,c#,decimal,precision,C#,Decimal,Precision,C#System.Decimal会记住输入时尾随的零的数量,这有什么原因吗? 请参见以下示例: public void DoSomething() { decimal dec1 = 0.5M; decimal dec2 = 0.50M; Console.WriteLine(dec1); //Output: 0.5 Console.WriteLine(dec2); //Output: 0.50 Console.Wr

C#System.Decimal会记住输入时尾随的零的数量,这有什么原因吗? 请参见以下示例:

public void DoSomething()
{
    decimal dec1 = 0.5M;
    decimal dec2 = 0.50M;
    Console.WriteLine(dec1);            //Output: 0.5
    Console.WriteLine(dec2);            //Output: 0.50
    Console.WriteLine(dec1 == dec2);    //Output: True
}

小数被归类为相等,但dec2记得它是用额外的零输入的。这是什么原因/目的?

小数表示固定精度的十进制值。文字值
0.50M
嵌入了2位小数的精度,因此创建的十进制变量会记住它是一个2位小数的值。行为完全是故意的


数值比较是对数值进行精确的数值相等性检查,因此,此处尾随的零不会影响结果。

表示一个数字可能很有用,包括其精度-因此0.5m可用于表示“0.45m到0.55m之间的任何值”(具有适当的限值),0.50m可用于表示“0.495米到0.545米之间的任何东西”

我怀疑大多数开发人员实际上并没有使用这个功能,但我可以看出它有时是多么有用


我相信这种能力最早出现在.NET 1.1中,顺便说一句-我认为1.0中的小数总是被有效地规范化了。

我认为这样做是为了为从数据库检索的数值提供更好的内部表示。数据库引擎在以十进制格式存储数字方面有着悠久的历史(避免舍入错误)对于值中的位数有明确的说明


以SQL Server为例进行比较。

“固定精度”在这里可能会产生误导。它是一种浮点类型,如
float
double
——只是点是小数点而不是二进制点(并且限制不同).出于所解释的原因,0.5和0.50确实有不同的信息。精度在某些领域非常相关,即数学和化学。这将是一个不错的理论,除了除法运算返回的位数与除数或被除数中的位数无关。对于大多数需要multi应用或除法,似乎
Decimal
应该提供一种方法来乘以
Double
,并将结果四舍五入到指定的精度级别;如果结果不能容纳那么多精度,则抛出一个异常。否则,
Decimal
将失去其语义优势,而不是将值放大100(或每货币单位的细分数)并使用
Double
@supercat:Hmm…关于细分部分,你当然是对的。理论可能仍然是能够表示数字及其准确性的能力,但实践是,它没有很好地用于算术。(当然,当从另一个源传播数据时,它仍然很有用。)@JonSkeet:如果我设计的是
Decimal
类型,我不会包含两个
Decimal
的乘法或除法运算符;相反,我需要具有指定精度的参数的函数。不过,我可能会包括
Decimal
times
Integer
Decimal
times
Long
运算符。我“我也会在运算符截断精度时抛出异常。不过,对于大多数金融应用程序,我认为在许多情况下,最好的类型是将
双精度
与比例因子(指定为数字,而不是幂,以允许非十进制货币)串联在一起。”@supercat:我不明白为什么一个
Double
(它本质上使用2的幂,而不是数字,作为一个刻度-一旦去掉它,它就不再是一个
Double
)这将是一个明智的选择。老实说,我也不认为支持非十进制货币真的很重要。有多少开发人员的生活会从这种支持中受益?具体来说,.NET的十进制类型和SQL server的十进制类型之间的映射可能会产生问题。如果使用
decimal(19,6)
在数据库中,C#中的
十进制
,然后用户输入
0.5M
,当您存储它并从数据库中检索它时,您将返回
0.500000
,这比用户输入的精度更高。您必须将精度存储在单独的字段中,或者对所有值的字段施加设置精度s