在C#中最适合用来赚钱的数据类型是什么?


426

在C#中最适合用来赚钱的数据类型是什么?


4
您可能会发现这篇文章的答案很有帮助。
ntombela


此外,如果使用数据的注释,包括using System.ComponentModel.DataAnnotations;... [DataType(DataType.Currency)] msdn.microsoft.com/en-us/library/...
JohnLBevan

Answers:


422

正如十进制所描述的那样:

十进制关键字表示128位数据类型。与浮点类型相比,十进制类型具有更高的精度和更小的范围,这使其适用于财务和货币 计算。

您可以使用小数,如下所示:

decimal myMoney = 300.5m;

41
您应该解释该链接的重要性。答案本身应该足够好,并带有链接作为其他参考或详细信息。请参阅stackoverflow.com/help/how-to-answer
TheRubberDuck

2
因此,最小长度的答案可以比最小长度的注释更少的字符-有趣!我的简洁答案不是一个问题,尤其是当它也“深入”时,它可以链接到进一步的讨论。
B. Clay Shannon

3
令人惊奇的答案,我认为它不需要进一步解释,因为它可以完全回答问题。就我而言,指向MSDN文档的链接是一个额外的奖励。太棒了!
特雷森

@Leee Treveil,这笔钱是多少(9.0098)表示指向点后第4个字符
SAR

114

系统十进制

十进制值类型表示十进制数,范围从正数79,228,162,514,264,337,593,543,950,335到负数79,228,162,514,264,337,593,543,950,335。十进制值类型适用于需要大量有效整数和小数位数且无舍入误差的财务计算。十进制类型不能消除舍入的需要。相反,它使由于舍入而产生的错误最小化。

我想指出zneak给出的出色答案,说明为什么不应该使用double。


68

使用来自企业应用程序架构模式Money模式 ; 将金额指定为小数,将货币指定为枚举。


2
我实际上是在建议这一点,但是我将Currency设为一类,因此可以定义汇率(相对于“基本货币”,通常是美元[我将其设置为1.00])。
Thomas Owens

5
对于这个线程的未来访问者(像我一样),现在有了这个:nuget.org/packages/Money,它动摇了!
Korijn 2014年

想知道这样的类型应该是结构还是类。十进制+一个(int)枚举使它成为20个字节。我的钱还在结构上。
nawfal

那个Moneynuget有一个指向项目站点的github链接,所以...没有文档?
乔治·莫尔

这样做的问题是,如果要创建自己的实现,则必须弄清楚如何真正实现它。最流行的ORM(EF)完全不支持自定义数据类型。因此有人问得到真正深的杂草做什么应该是一个非常简单的事情。
乔治·莫尔

25

十进制。如果您选择double,则很容易出现舍入错误


8
@Jess double会引入舍入错误,因为浮点不能完全表示所有数字(例如0.01不能精确表示浮点数)。Decimal,而另一方面,代表数字准确。(折衷Decimal范围小于浮点数)浮点数会给您*无意*舍入误差(例如0.01+0.01 != 0.02)。Decimal会给您舍入错误,但只有在您要求时才出​​现(例如,Math.Round(0.01+0.02)返回零)
Ian Boyd

2
@IanBoyd:值“ $ 1.57”可以精确表示(双精度)157。如果double在适当的情况下使用并仔细应用了缩放和特定于域的舍入,则可以非常精确。如果某人四舍五入,decimal可能会产生语义上不正确的结果(例如,如果将多个值加在一起应被四舍五入到最接近的便士,但实际上并没有首先围绕它们)。唯一的好处decimal是缩放是内置的。
supercat 2012年

1
@supercat,关于此注释“如果将多个值加在一起应四舍五入到最接近的美分,但实际上并没有首先围绕它们”,我看不到浮点数将如何解决这个问题。这是用户错误,与小数点恕我直言无关。我的意思是正确的,但是我觉得它错位了,主要是因为IanBoyd确实指定了...如果您要的话。
2013年


13

同意Money模式:使用小数时,处理货币太麻烦了。

如果创建了货币类,则可以在其中放置与货币有关的所有逻辑,包括正确的ToString()方法,更多的解析值控制和更好的除法控制。

同样,对于Currency类,不可能无意间将金钱与其他数据混淆。


10

另一个选择(特别是如果要滚动自己的类)是使用int或int64,并将低四位数字(甚至可能是2)指定为“小数点右边”。因此,“在边缘”在进入时需要一些“ * 10000”,在离开时需要一些“ / 10000”。这是Microsoft SQL Server使用的存储机制,请参阅http://msdn.microsoft.com/zh-cn/library/ms179882.aspx

唯一的问题是,您所有的求和都可以使用(快速)整数算术完成。


7

我使用过的大多数应用程序 decimal用来代表金钱的。这是基于以下假设:应用程序永远不会涉及一种以上的货币。

该假设可能基于另一个假设,即该应用程序将永远不会在其他使用不同货币的国家/地区使用。我见过一些证明是错误的情况。

现在,这一假设正在以一种新的方式受到挑战:比特币等新货币正变得越来越普遍,而且它们并非特定于任何国家。仅在一个国家/地区使用的应用程序可能仍需要支持多种货币并非不现实。

有人会说创建或什至只是为了赚钱而创建的类型就是“镀金”,或者增加了超出已知要求的复杂性。我非常不同意。一个概念在您的领域中越普遍,那么做出合理的努力以预先使用正确的抽象就越重要。如果您想了解复杂性,请尝试使用一个曾经使用过的应用程序,decimal现在Currency每个decimal属性旁边都有一个附加属性。

如果您预先使用了错误的抽象,那么以后进行替换将使工作量增加100倍。这意味着可能会在现有代码中引入缺陷,而最好的部分是这些缺陷可能涉及金钱,金钱交易或任何金钱交易。

使用十进制以外的其他语言并不难。Google是“零花钱类型”,您会看到许多开发人员都创建了这样的抽象(包括我自己)。这很容易。就像使用DateTime而不是将日期存储在中一样简单string


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.