【问题标题】:Go type for purchasing/financial calculations用于采购/财务计算的 Go 类型
【发布时间】:2014-11-18 10:07:08
【问题描述】:

我正在用 Go 建立一个在线商店。正如所料,一些重要的部分需要记录准确的货币金额。我知道与浮点数相关的舍入问题(即 0.3 无法准确表示等)。

货币的概念似乎很容易仅表示为字符串。但是,我不确定哪种类型最适合表达实际金额。

关键要求似乎是:

  • 可以根据货币将小数精确表示到指定的小数位数(某些货币使用超过 2 个小数位:http://www.londonfx.co.uk/ccylist.html
  • 显然需要基本的算术运算 - add/sub/mul/div。
  • 合理的字符串转换 - 这基本上意味着转换为它的十进制等效值。此外,国际化至少需要成为可能,即使没有内置所有逻辑(欧洲为 1.000,美国为 1,000)。
  • 四舍五入,可能使用银行家四舍五入等其他四舍五入方案。
  • 需要有一种简单明了的方式来对应数据库值——在我的例子中是 MySQL。 (在此级别将值视为字符串可能最有意义,以确保其值得到准确保留。)

我知道 math/big.Rat 并且它似乎解决了很多这些问题,但是例如它的字符串输出不会按原样工作,因为它会以“a/b”形式输出.我确信也有解决方案,但我想知道是否存在某种我不知道(不容易找到)的现有最佳实践。

更新:这个包看起来很有前途:https://code.google.com/p/godec/

【问题讨论】:

  • 快速反应:认为您实际上想要一个包含单位、文化(因为欧元金额在不同国家/地区以不同方式打印)和金额的 struct 类型,可能作为定点整数(例如, 对于美元、美分或美分*10;存储的精度可能因国家/地区而异,或者您始终可以使用 4 位数字来控制舍入误差)。如果您想控制舍入,我认为您必须通过方法(即 amt.Div(3) 而不是 amt.Units /= 3)对数学运算进行门控。
  • 存储它自己有趣的东西;您可能需要 三个 数据库列,即金额、货币以及在交易时大致转换为客户标准货币的金额,无论货币存储在何处。
  • 我无法快速找到现有模型,但总的来说,我认为您会想要自己实现一些东西,这比 fire and motion 更聪明。
  • 哦,嘿,不能保证,但请检查 oot github.com/Confunctionist/finance
  • @twotwotwo 感谢您的信息 - 是的,我想我得自己动手了;是的,制作一个封装货币和金额的结构(可能使用 big.Rat)确实很有意义。在我的情况下,我在 UI 层分别跟踪语言环境(语言+国家/地区),因为货币和金额会影响预期的实际“价格”,而语言环境实际上只是一个显示的东西,并决定了你如何格式化它对于正在查看它的特定用户。

标签: go bigdecimal financial


【解决方案1】:

您应该让 i18n 与您的货币实施脱钩。所以不,不要将所有内容捆绑在一个结构中并收工。标记金额代表什么货币,仅此而已。让 i18n 处理格式化、字符串化、前缀等。

使用任意精度的数字类型,例如 math/big.Rat。如果这不是一个选项(由于序列化限制或其他障碍),那么使用最大的固定大小整数类型,你可以用你所代表的任何货币来表示原子货币的数量——美分代表美元,日元代表日元,瑞士法郎为 rappen,欧元为美分,等等。

在使用第二种方法时,请特别注意不要导致溢出,并为除法定义清晰且有意义的舍入行为。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-03-30
    • 1970-01-01
    • 1970-01-01
    • 2022-12-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多