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(),以确保相同的输出,无论变量如何初始化?
所述NumberDecimalDigits
属性用于与"F"
和"N"
的标准格式字符串,而不是ToString
方法称为无格式字符串。
您可以使用:
Console.WriteLine(a.ToString("N", numberFormat));
如何使它输出始终已回答了,但这里的问题是,为什么他们不同的输出摆在首位:
甲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后缀是decimal类型。 例如,文字1M,1.5M,1e10m,和123.456M都是十进制类型。 此实数通过取精确值使用银行家的舍入转换为十进制值,并且,如有必要,四舍五入到最接近的表示值(§4.1.7)。 任何规模的字面表观保留除非值被四舍五入或值为零(在该后者的情况下的符号和规模将是0)。 因此,文字2.900米将被解析,以形成具有符号0,系数2900,和标度3小数。
试试这个:
Console.WriteLine(String.Format("{0:0.00}", a));
Console.WriteLine(String.Format("{0:0.00}", b));
输出将始终小数点后2例。 更多的例子在这里:
http://www.csharp-examples.net/string-format-double/