var numberFormat = new NumberFormatInfo();
numberFormat.NumberDecimalSeparator = ".";
numberFormat.NumberDecimalDigits = 2;
decimal a = 10.00M;
decimal b = 10M;
Console.WriteLine(a.ToString(numberFormat));
Console.WriteLine(b.ToString(numberFormat));
Console.WriteLine(a == b ? "True": "False");
在控制台中: 10.00 10 真
为什么会有所不同?更重要的是,无论变量如何初始化,如何调用ToString()以确保相同的输出?
答案 0 :(得分:4)
如何使其输出始终如一的问题已得到解答,但这就是为什么它们首先输出不同的原因:
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的小数。
答案 1 :(得分:2)
NumberDecimalDigits
属性与"F"
和"N"
标准格式字符串一起使用,而不是在没有格式字符串的情况下调用的ToString
方法。
您可以使用:
Console.WriteLine(a.ToString("N", numberFormat));
答案 2 :(得分:1)
试试这个:
Console.WriteLine(String.Format("{0:0.00}", a));
Console.WriteLine(String.Format("{0:0.00}", b));
输出总是2个十进制的情况。更多例子: