在 C# 中用于金钱的最佳数据类型是什么?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/693372/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
What is the best data type to use for money in C#?
提问by NotDan
What is the best data type to use for money in C#?
在 C# 中用于金钱的最佳数据类型是什么?
采纳答案by Lee Treveil
As it is described at decimalas:
正如十进制描述的那样:
The decimal keyword indicates a 128-bit data type. Compared to floating-point types, the decimal type has more precision and a smaller range, which makes it appropriate for financial and monetarycalculations.
十进制关键字表示 128 位数据类型。与浮点类型相比,decimal 类型具有更高的精度和更小的范围,这使其适用于金融和货币计算。
You can use a decimal as follows:
您可以按如下方式使用小数:
decimal myMoney = 300.5m;
回答by David Walschots
The Decimal value type represents decimal numbers ranging from positive 79,228,162,514,264,337,593,543,950,335 to negative 79,228,162,514,264,337,593,543,950,335. The Decimal value type is appropriate for financial calculations requiring large numbers of significant integral and fractional digits and no round-off errors. The Decimal type does not eliminate the need for rounding. Rather, it minimizes errors due to rounding.
Decimal 值类型表示从正 79,228,162,514,264,337,593,543,950,335 到负 79,228,162,514,264,337,593,543,950,335 的十进制数。Decimal 值类型适用于需要大量有效整数和小数位且没有舍入错误的财务计算。Decimal 类型不会消除四舍五入的需要。相反,它最大限度地减少了由于舍入而导致的错误。
I'd like to point to this excellent answerby zneak on why double shouldn't be used.
我想指出zneak 关于为什么不应该使用 double 的出色答案。
回答by SquidScareMe
Decimal. If you choose double you're leaving yourself open to rounding errors
十进制。如果你选择 double 你会让自己容易出现四舍五入错误
回答by dommer
decimal has a smaller range, but greater precision - so you don't lose all those pennies over time!
小数的范围更小,但精度更高 - 所以你不会随着时间的推移失去所有这些便士!
Full details here:
完整的细节在这里:
回答by lmsasu
Use the Money patternfrom Patterns of Enterprise Application Architecture; specify amount as decimal and the currency as an enum.
回答by Noel Kennedy
Create your own class. This seems odd, but a .Net type is inadequate to cover different currencies.
创建自己的类。这看起来很奇怪,但 .Net 类型不足以涵盖不同的货币。
回答by Lennaert
Agree with the Money pattern: Handling currencies is just too cumbersome when you use decimals.
同意货币模式:使用小数时处理货币太麻烦了。
If you create a Currency-class, you can then put all the logic relating to money there, including a correct ToString()-method, more control of parsing values and better control of divisions.
如果您创建一个 Currency 类,那么您可以将所有与货币相关的逻辑放在那里,包括正确的 ToString() 方法、对解析值的更多控制以及对除法的更好控制。
Also, with a Currency class, there is no chance of unintentionally mixing money up with other data.
此外,使用 Currency 类,不可能无意中将货币与其他数据混淆。
回答by dsz
Another option (especially if you're rolling you own class) is to use an int or a int64, and designate the lower four digits (or possibly even 2) as "right of the decimal point". So "on the edges" you'll need some "* 10000" on the way in and some "/ 10000" on the way out. This is the storage mechanism used by Microsoft's SQL Server, see http://msdn.microsoft.com/en-au/library/ms179882.aspx
另一种选择(特别是如果您滚动自己的课程)是使用 int 或 int64,并将低四位(甚至可能是 2)指定为“小数点右侧”。所以“在边缘”你需要一些“* 10000”在路上和一些“/ 10000”在出路。这是微软的SQL Server使用的存储机制,参见http://msdn.microsoft.com/en-au/library/ms179882.aspx
The nicity of this is that all your summation can be done using (fast) integer arithmetic.
这样做的好处是您可以使用(快速)整数算法完成所有求和。
回答by Scott Hannen
Most applications I've worked with use decimal
to represent money. This is based on the assumption that the application will never be concerned with more than one currency.
我使用过的大多数应用程序都decimal
用于表示金钱。这是基于应用程序永远不会涉及一种以上货币的假设。
This assumption may be based on another assumption, that the application will never be used in other countries with different currencies. I've seen cases where that proved to be false.
此假设可能基于另一个假设,即应用程序永远不会在其他货币不同的国家/地区使用。我见过证明这是错误的案例。
Now that assumption is being challenged in a new way: New currencies such as Bitcoin are becoming more common, and they aren't specific to any country. It's not unrealistic that an application used in just one country may still need to support multiple currencies.
现在,这一假设正以一种新的方式受到挑战:比特币等新货币正变得越来越普遍,而且它们并不特定于任何国家。仅在一个国家/地区使用的应用程序可能仍需要支持多种货币,这并非不现实。
Some people will say that creating or even using a type just for money is "gold plating," or adding extra complexity beyond the known requirements. I strongly disagree. The more ubiquitous a concept is within your domain, the more important it is to make a reasonable effort to use the correct abstraction up front. If you want to see complexity, try working in an application that used to use decimal
and now there's an additional Currency
property next to every decimal
property.
有些人会说,仅仅为了金钱而创造甚至使用一种类型是“镀金”,或者增加了超出已知要求的额外复杂性。我强烈反对。一个概念在您的领域中越普遍,就越有必要做出合理的努力来预先使用正确的抽象。如果您想了解复杂性,请尝试在曾经使用过的应用程序中工作decimal
,现在Currency
每个decimal
属性旁边都有一个附加属性。
If you use the wrong abstraction up front, replacing it later will be a hundred times more work. That means potentially introducing defects into existing code, and the best part is that those defects will likely involve amounts of money, transactions with money, or just anything with money.
如果您预先使用了错误的抽象,那么稍后替换它的工作量将增加一百倍。这意味着可能会在现有代码中引入缺陷,最好的部分是这些缺陷可能涉及大量金钱、金钱交易或任何金钱交易。
And it's not that difficult to use something other than decimal. Google "nuget money type" and you'll see that numerous developers have created such abstractions (including me.) It's easy. It's as easy as using DateTime
instead of storing a date in a string
.
使用十进制以外的其他东西并不难。谷歌“nuget money type”,你会看到许多开发人员已经创建了这样的抽象(包括我)。这很容易。它就像使用DateTime
而不是将日期存储在string
.