【问题标题】:BigDecimal and MoneyBigDecimal 和金钱
【发布时间】:2012-03-31 20:13:04
【问题描述】:

我研究并发现在处理货币时,进行计算的最佳方法是使用BigDecimal 类。

考虑到这一点,我正在编写一个代码,将各种类型的外币转换成美元,反之亦然(具体来说,一个收银机可以将外币转换成美元,计算零钱并返回此金额以外币支付给客户)。

截至目前,许多方法使用double,其中两个将int 作为参数用于计算美国货币。

问题:

由于我想在计算中使用 BigDecimal 类,我是否应该将所有涉及双精度数的计算方法更改为 BigDecimal?

【问题讨论】:

  • 是的,这听起来是个好主意。 1+ 表示希望避免为此使用浮点数。
  • 另一种用钱计算的实用方法是有理数。它们具有“无限”精度、稳定且比 BigDecimal 更快。

标签: java bigdecimal


【解决方案1】:

是的,您应该将所有浮点数或双精度数更改为整数、长整数或BigDecimals

浮点数和双精度数对于财务计算并不精确。使用Money 模式处理金额和货币是一个非常好的主意(它是Quantity 的一种特殊类型)。要维护可能以多种货币形式出现的资金列表,您实际上要做的是MoneyBagMoney 的集合,然后可以将给定目标货币和CurrencyExchangeService 的所有值相加(货币兑换率也应该存储为BigDecimals)。

每次运算后都应根据所需的小数位数和舍入算法进行舍入。小数位数通常是Currency 的一个属性(例如,ISO 4217);除非需要不同的数字(例如在为汽油定价时)。

你绝对应该看看 Fowler 的例子;但我还为exercise 创建了一个非常简单的单一货币Money 类。它仅使用美元并四舍五入到小数点后 2 位;但它仍然是未来扩展的良好基础。

【讨论】:

  • 有时财务计算采用更复杂的方法。例如。一个典型的例子是将一个数量分成 n% 和 (100-n)% 的部分,以便这些部分的总和是完美的,尽管四舍五入。
  • @9000:是的,Fowler 描述了一个分配算法,看看 PoEAA;我之前也使用过,非常成功...
  • @9000:我找到了算法here
  • ^^那是 Jordao 和 9000,我想我只需要使用 BigDecimal。
  • @Wormhole99:那么,您有多种货币但仍然不会创建Money 类?你应该强烈考虑它。抽象将使您的程序更易于理解和维护。
【解决方案2】:

是的,BigDecimal 肯定是正确的方法(浮点数几乎从不)。也在 JDBC 中。

但话虽如此,四舍五入存在问题。在某些情况下,欧洲软件法律要求 6 位小数。通常,您需要在每一步中舍入 2 个位置。如果您有一个带有 2 位小数的数量和一个价格,您将得到 4 个小数,并且必须四舍五入。所以为了让丑陋的 BigDecimal 界面更丑,你可能需要一些帮助函数(multiplyRounded?)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-12-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多