1
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() 以确保相同的输出?

4

3 回答 3

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 的小数。

于 2012-12-10T23:38:22.960 回答
2

NumberDecimalDigits属性"F""N"标准格式字符串一起使用,而不是在ToString没有格式字符串的情况下调用的方法。

您可以使用:

Console.WriteLine(a.ToString("N", numberFormat));
于 2012-12-10T23:18:37.053 回答
1

试试这个:

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/

于 2012-12-10T23:19:53.450 回答