【发布时间】: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