十进制存储C#中解析字符串的精度?有什么影响?

Pol*_*ial 15 c# string decimal string-formatting

在IRC的谈话中,有人指出以下内容:

decimal.Parse("1.0000").ToString() // 1.0000
decimal.Parse("1.00").ToString() // 1.00
Run Code Online (Sandbox Code Playgroud)

decimal类型如何/为什么保留这样的精度(或者更确切地说,重要数字)?我的印象是这两个值是相等的,不是很明显.

这也提出了进一步的问题:

  • 在数学运算期间,有效数字的数量是如何确定的?
  • 序列化期间是否保留了重要数字的数量?
  • 当前的文化会影响这种处理方式吗?

ole*_*sii 9

在数学运算期间,有效数字的数量是如何确定的?

这在ECMA-334 C#4规范11.1.7 p.112中规定

十进制表示为以十的幂为单位的整数.对于绝对值小于1.0m的小数,该值至少精确到小数点后第28位.对于绝对值大于或等于1.0m的小数,该值精确到至少28位.

序列化期间是否保留了重要数字的数量?

是的,通过串行化,值和精度不会改变

[Serializable]
public class Foo
{
    public decimal Value;
}

class Program
{
    static void Main(string[] args)
    {
        decimal d1 = decimal.Parse("1.0000");
        decimal d2 = decimal.Parse("1.00");

        Debug.Assert(d1 ==d2);

        var foo1 = new Foo() {Value = d1};
        var foo2 = new Foo() {Value = d2};

        IFormatter formatter = new BinaryFormatter();
        Stream stream = new FileStream("data.bin", FileMode.Create, FileAccess.Write, FileShare.None);
        formatter.Serialize(stream, d1);
        stream.Close();

        formatter = new BinaryFormatter();
        stream = new FileStream("data.bin", FileMode.Open, FileAccess.Read, FileShare.Read);
        decimal deserializedD1 = (decimal)formatter.Deserialize(stream);
        stream.Close();

        Debug.Assert(d1 == deserializedD1);

        Console.WriteLine(d1); //1.0000
        Console.WriteLine(d2); //1.00
        Console.WriteLine(deserializedD1); //1.0000

        Console.Read();
    }
}
Run Code Online (Sandbox Code Playgroud)

当前的文化会影响这种处理方式吗?

当前文化只影响如何从字符串中解析小数,例如它可以处理'.' ','作为文化特定的小数点符号或货币符号,如果您提供它,例如"£123.4500".文化不会改变对象在内部存储的方式,也不会影响其精度.

在内部,十进制有一个尾数,一个指数和一个符号,所以没有任何其他空间.