如何使其输出一致的问题已经得到解答,但这就是为什么它们首先输出不同的原因:
值在decimal
内部包含标度和系数字段。在 的情况下10M
,编码值的系数为 10,比例为 0:
10M = 10 * 10^0
在 的情况下10.00M
,编码值的系数为 1000,比例为 2:
10.00M = 1000 * 10^(-2)
您可以通过检查内存中的值来看到这一点:
unsafe
{
fixed (decimal* array = new decimal[2])
{
array[0] = 10M;
array[1] = 10.00M;
byte* ptr = (byte*)array;
Console.Write("10M: ");
for (int i = 0; i < 16; i++)
Console.Write(ptr[i].ToString("X2") + " ");
Console.WriteLine("");
Console.Write("10.00M: ");
for (int i = 16; i < 32; i++)
Console.Write(ptr[i].ToString("X2") + " ");
}
}
输出
10M: 00 00 00 00 00 00 00 00 0A 00 00 00 00 00 00 00
10.00M: 00 00 02 00 00 00 00 00 E8 03 00 00 00 00 00 00
(0xA 是十六进制的 10,0x3E8 是十六进制的 1000)
C# 规范的第 2.4.4.3 节概述了此行为:
以 M 或 m 为后缀的实数是十进制类型。例如,文字 1m、1.5m、1e10m 和 123.456M 都是十进制类型。该文字通过取确切值转换为十进制值,并在必要时使用银行四舍五入(第 4.1.7 节)四舍五入到最接近的可表示值。除非值被四舍五入或值为零(在后一种情况下,符号和比例将为 0),否则文字中明显的任何比例都会被保留。因此,文字 2.900m 将被解析为符号 0、系数 2900 和小数位数 3 的小数。