在 C# 中用于赚钱的最佳数据类型是什么?
using System.ComponentModel.DataAnnotations;
... [DataType(DataType.Currency)]
msdn.microsoft.com/en-us/library/…
如 decimal 所述:
十进制关键字表示 128 位数据类型。与浮点类型相比,十进制类型的精度更高,范围更小,适用于金融和货币计算。
您可以按如下方式使用小数:
decimal myMoney = 300.5m;
Decimal 值类型表示从正数 79,228,162,514,264,337,593,543,950,335 到负数 79,228,162,514,264,337,593,543,950,335 的十进制数。 Decimal 值类型适用于需要大量有效整数和小数位数且无舍入错误的财务计算。 Decimal 类型不会消除舍入的需要。相反,它最大限度地减少了由于四舍五入引起的错误。
我想通过 zneak 指出为什么不应该使用 double 的 this excellent answer。
使用 Patterns of Enterprise Application Architecture 中的 Money pattern。将金额指定为小数,将货币指定为枚举。
Money
nuget 有一个项目站点的死 github 链接,所以...没有文档?
十进制。如果您选择双精度数,您将面临舍入错误
double
可能会引入舍入错误,因为浮点不能准确表示所有数字(例如 0.01 在浮点中没有准确表示)。 Decimal
,另一方面,确实代表数字准确。 (权衡是 Decimal
的范围比浮点数更小)浮点数可能会给您*不经意的*舍入错误(例如 0.01+0.01 != 0.02
)。 Decimal
可以给你舍入错误,但只有当你要求它时(例如 Math.Round(0.01+0.02)
返回零)
double
并在适当的时候仔细应用缩放和特定于域的舍入,它可以非常精确。如果四舍五入时马虎,decimal
可能会产生语义不正确的结果(例如,如果将多个值相加,这些值应该四舍五入到最接近的一美分,但实际上并没有首先围绕它们)。 decimal
的唯一好处是它内置了缩放功能。
小数的范围更小,但精度更高 - 所以你不会随着时间的推移失去所有这些便士!
完整的细节在这里:
http://msdn.microsoft.com/en-us/library/364x0z75.aspx
同意货币模式:使用小数时处理货币太麻烦了。
如果你创建一个 Currency 类,你可以把所有与钱相关的逻辑放在那里,包括一个正确的 ToString() 方法,更多的解析值控制和更好的分割控制。
此外,使用 Currency 类,不可能无意中将钱与其他数据混在一起。
另一种选择(特别是如果您正在滚动自己的课程)是使用 int 或 int64,并将低四位(甚至可能是 2)指定为“小数点右侧”。所以“在边缘”你需要一些“* 10000”在路上,一些“/ 10000”在离开的路上。这是 Microsoft 的 SQL Server 使用的存储机制,请参阅 http://msdn.microsoft.com/en-au/library/ms179882.aspx
这样做的好处是你所有的求和都可以使用(快速)整数算术来完成。
我使用过的大多数应用程序都使用 decimal
来表示金钱。这是基于应用程序永远不会关注超过一种货币的假设。
这个假设可能基于另一个假设,即应用程序永远不会在其他国家使用不同的货币。我见过被证明是错误的案例。
现在,这种假设正以一种新的方式受到挑战:比特币等新货币正变得越来越普遍,而且它们并不特定于任何国家。仅在一个国家使用的应用程序可能仍需要支持多种货币并非不现实。
有些人会说,为了钱而创建甚至使用类型是“镀金”,或者增加了超出已知要求的额外复杂性。我强烈反对。一个概念在您的领域中越普遍,做出合理的努力以预先使用正确的抽象就越重要。如果您想了解复杂性,请尝试在以前使用 decimal
的应用程序中工作,现在每个 decimal
属性旁边都有一个额外的 Currency
属性。
如果你预先使用了错误的抽象,那么以后替换它将会增加一百倍的工作量。这意味着可能会在现有代码中引入缺陷,最好的部分是这些缺陷可能涉及大量金钱、金钱交易或任何金钱交易。
使用十进制以外的东西并不难。谷歌“nuget money type”,您会看到许多开发人员(包括我)创建了这样的抽象。这很容易。这就像使用 DateTime
而不是将日期存储在 string
中一样简单。
创建自己的班级。这看起来很奇怪,但 .Net 类型不足以涵盖不同的货币。