用整数/大整数与大十进制表示货币



几年前,我帮助编写了一个处理金钱和保险的应用程序。 最初,我们用浮点数来表示货币(我知道这是一个很大的禁忌)。 大多数应用程序只是加减值,因此没有任何问题。 然而,特定部分涉及货币价值的百分比,因此乘法和除法。

我们立即开始遭受浮点错误的困扰,不得不进行重大重构。 我们使用了任意精度库来解决这个问题。 然而,它并没有改变你最终可以得到几分之一美分的事实。 你应该如何四舍五入? 简短的回答是"这很复杂"。

现在我正准备开始开发一个类似的应用程序来取代旧的应用程序。 多年来我一直在考虑这个问题。 我一直认为最简单的方法是创建一个货币数据类型,该数据类型包装一个整数(或BigInteger)来表示便士的数量,并具有将其打印为传统的,人性化的$0.00格式的函数。

然而,在研究这个问题时,我发现了JSR 354,这是最近实现的Java Money API。 我很惊讶地发现它用BigDecimal支持其货币代表. 因此,它包括舍入的特定逻辑。

在计算中携带几分之一美分的优势是什么? 为什么我要这样做,而不是说一分钱是货币的"原子"形式?

这是一个广泛的问题,因为它的答案因实施而异。

如果我以 5 美元的价格批量购买 1000 件物品,那么每件物品的价格为 0.005 美元,这低于您声称的"原子形式"货币 0.01 美元。

如果我们认为 0.01 美元是可能的最低金额,那么我们将无法在特定情况下处理计算,就像我示例中的计算一样。

出于这个原因,JavaMoney API处理许多小数位数,确保在这种情况下不会丢失精度。