【问题标题】:What is the best data type to use for money in C#?在 C# 中用于赚钱的最佳数据类型是什么?
【发布时间】:2010-10-16 03:43:25
【问题描述】:

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

【问题讨论】:

标签: c# types currency


【解决方案1】:

正如decimal 所描述的那样:

decimal 关键字表示 128 位数据类型。相比 浮点类型,十进制类型具有更高的精度和 范围更小,这使得它适合金融和货币 计算。

您可以按如下方式使用小数:

decimal myMoney = 300.5m;

【讨论】:

  • 您应该解释该链接的重要性。一个答案本身应该足够好,并带有一个链接作为额外的参考或细节。见stackoverflow.com/help/how-to-answer
  • 因此,最小长度的答案可以比最小长度的注释包含更少的字符 - 有趣!并不是说我对简洁/简洁的答案有问题,尤其是当它也“深刻”,因为它链接到进一步的讨论时。
  • 惊人的答案,我觉得不需要进一步解释,因为它完全回答了这个问题。就我而言,指向 MSDN 文档的链接是一个奖励。太棒了!
【解决方案2】:

System.Decimal

Decimal 值类型表示从正数 79,228,162,514,264,337,593,543,950,335 到负数 79,228,162,514,264,337,593,543,950,335 的十进制数。 Decimal 值类型适用于需要大量有效整数和小数位数且无舍入错误的财务计算。 Decimal 类型不会消除舍入的需要。相反,它可以最大限度地减少因四舍五入引起的错误。

我想指出 zneak 的 this excellent answer 为什么不应该使用 double。

【讨论】:

    【解决方案3】:

    使用Patterns of Enterprise Application Architecture 中的Money pattern。将金额指定为小数,货币指定为枚举。

    【讨论】:

    • 我实际上是要提出这个建议,但我将 Currency 设为一个类,这样我就可以定义汇率(相对于“基础货币”,通常是美元 [我设置为1.00 的汇率])。
    • 对于这个线程的未来访问者(比如我),现在有这个:nuget.org/packages/Money,它摇滚!
    • 想知道这样的类型应该是结构还是类。十进制 + (int) 枚举使其为 20 个字节。我的钱还在 struct 上。
    • Money nuget 有一个用于项目站点的死 github 链接,所以...没有文档?
    • 这个问题是如果你正在创建自己的实现,你必须弄清楚如何真正持久化它。最流行的 ORM (EF) 根本不支持自定义数据类型。因此,有人被要求真正深入杂草,去做一件应该很简单的事情。
    【解决方案4】:

    十进制。如果您选择双精度数,您将面临舍入错误

    【讨论】:

    • @Jess double 可能会引入舍入误差,因为浮点数不能精确地表示所有数字(例如,0.01 在浮点数中没有精确的表示)。 Decimal,另一方面,确实代表数字完全。 (权衡是Decimal 的范围比浮点小)浮点会给你*无意*舍入错误(例如0.01+0.01 != 0.02)。 Decimal 可以给你舍入错误,但只有当你要求它时(例如Math.Round(0.01+0.02) 返回零)
    • @IanBoyd:值“$1.57”可以精确表示(双)157。如果一个人使用double 并在适当的时候仔细应用缩放和特定领域的舍入,它可以非常精确。如果一个人的四舍五入马虎,decimal 可能会产生语义上不正确的结果(例如,如果一个人将多个值相加,这些值应该四舍五入到最接近的一美分,但实际上并没有首先围绕它们)。 decimal 唯一的好处是它内置了缩放功能。
    • @supercat,关于此评论“如果将多个值加在一起,这些值应该四舍五入到最接近的一美分,但实际上并没有首先围绕它们”,我看不出浮点数会如何解决这个问题。这是一个用户错误,与小数恕我直言无关。我确实明白这一点,但我觉得它放错了地方,主要是因为 IanBoyd 确实指定了……如果你要求的话。
    【解决方案5】:

    十进制的范围更小,但精度更高 - 因此您不会随着时间的推移失去所有这些便士!

    这里有完整的细节:

    http://msdn.microsoft.com/en-us/library/364x0z75.aspx

    【讨论】:

      【解决方案6】:

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

      如果您创建一个 Currency-class,那么您可以将所有与货币相关的逻辑放在那里,包括正确的 ToString() 方法、对解析值的更多控制以及对分割的更好控制。

      此外,使用 Currency 类,不会无意中将钱与其他数据混在一起。

      【讨论】:

        【解决方案7】:

        另一种选择(特别是如果您正在滚动自己的课程)是使用 int 或 int64,并将低四位(甚至可能是 2)指定为“小数点右侧”。所以“在边缘”你需要一些“* 10000”在路上,一些“/ 10000”在离开的路上。这是微软的SQL Server使用的存储机制,见http://msdn.microsoft.com/en-au/library/ms179882.aspx

        这样做的好处是所有的求和都可以使用(快速)整数算术来完成。

        【讨论】:

          【解决方案8】:

          我使用过的大多数应用程序都使用decimal 来代表金钱。这是基于应用程序永远不会关注超过一种货币的假设。

          此假设可能基于另一个假设,即该应用程序永远不会在其他国家使用不同货币的国家。我见过被证明是错误的案例。

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

          有些人会说,为了钱而创建甚至使用类型是“镀金”,或者增加了超出已知要求的额外复杂性。我强烈反对。一个概念在你的领域中越普遍,做出合理的努力来预先使用正确的抽象就越重要。如果您想了解复杂性,请尝试在以前使用 decimal 的应用程序中工作,现在每个 decimal 属性旁边都有一个额外的 Currency 属性。

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

          而且使用十进制以外的东西并不难。谷歌“nuget money type”,你会看到许多开发人员(包括我)创建了这样的抽象。这很容易。就像使用 DateTime 一样简单,而不是将日期存储在 string 中。

          【讨论】:

            【解决方案9】:

            创建您自己的课程。这看起来很奇怪,但 .Net 类型不足以涵盖不同的货币。

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 2022-01-18
              • 2016-03-03
              • 2021-12-14
              • 1970-01-01
              • 1970-01-01
              • 2013-09-20
              • 1970-01-01
              相关资源
              最近更新 更多