在C#中处理货币金额的最佳做法

Gur*_*epS 9 c# types currency

我读过几篇关于某些数据类型用于存储货币金额的危险的文章.不幸的是,一些概念不在我的舒适区.

阅读这些文章后,在C#中使用资金的最佳做法和建议是什么?我应该使用少量的特定数据类型和更大数量的不同数据类型吗?此外,我在英国,这意味着我们使用,(例如£4,000,而其他文化代表相同的数量不同).

Joe*_*son 16

十进制是货币金额最合理的类型.

Decimal是一个浮点数10数字类型,精度为28+十进制数.使用Decimal,您将获得比使用base 2 Double类型更少的惊喜.

Double使用的内存是Decimal的一半,而Double会因为许多常见浮点运算的CPU硬件而快得多,但它不能准确地代表大多数基本10分数(例如1.05)并且具有不太准确的15+十进制数字精确.Double确实具有更多范围的优势(它可以代表更大和更小的数字),这对于某些计算可以派上用场,特别是一些统计计算.

您的问题的一个答案是,Decimal是固定点,带有4位十进制数字.不是这种情况.如果您对此有疑问,请注意以下代码行产生0.0000000001:

Console.WriteLine("number={0}", 1m / 10000000000m);
Run Code Online (Sandbox Code Playgroud)

说完所有这些之后,值得注意的是,世界上使用最广泛的使用货币金额的软件Microsoft Excel使用了双打.当然,他们必须通过大量的箍来使其运作良好,并且仍然有一些不足之处.在Excel中尝试这两个公式:

  • = 1-0.9-0.1
  • =(1-0.9-0.1)

第一个产生0,第二个产生〜-2.77e-17.在某些情况下,Excel在添加和减去数字时实际上会对数字进行按摩,但并非在所有情况下都是如此.


Ed *_* S. 8

由于舍入错误,您不应使用浮点数.小数类型应该适合你.


dan*_*gph 6

Martin Fowler建议使用Money类.请参阅相关链接.他的想法有很多实现,或者你可以编写自己的想法.Fowler自己的实现是用Java编写的,所以他使用了一个类.我见过的C#版本使用了一个结构,这似乎是明智的.