我意识到我们应该使用BigDecimal
所有货币价值,但是美元的股票价格呢?
我注意到来自主要供应商的数据馈送 API 使用double
股票报价的类型。有谁知道为什么?
这是否意味着我的应用程序可以使用该类型double
来存储来自这些供应商的股票报价?
不使用二进制浮点数的原因是货币使用小数,人们(和会计法规)期望对其执行的算术运算具有特定的十进制行为——二进制浮点不提供。
但是,股票报价提要通常不用于会计。它们被显示、比较、用作各种图表分析指标或交易算法的输入——所有这些都比会计更接近科学应用,并且不需要小数行为或精度。相反,由于数据量很大,存储效率和性能是相关的,而且BigDecimal
真的很糟糕。
我在外地工作。从精度的角度来看,BigDecimal 显然是理想的,但从性能的角度来看却很糟糕。在某些情况下双倍是一种选择(特别是在处理正常股票价格时,双倍很容易 - 采取适当的预防措施 - 能够代表我经常处理的所有股票交易所的整个价格范围)。
另一种选择是,如果您知道相关交易所使用的 DP 范围,则使用定点和普通 int 或 long。举个我熟悉的例子,Xetra(德国电子交易所)目前最多有 3 个小数位。使用 3dp,您可以使用正常的 int 表示最高 2,147,483.647 的价格。对单个价格罚款,对代表一天的总交易量没有好处。
这完全取决于您接收到什么数据、这些数据的精度是多少以及您如何处理它。
我拒绝将 BigDecimal 用于货币价值(通常*)。使用设计用于货币的数据类型(具有最低精度,例如美元的 mils)并且知道如何处理其他规则。这也可以用来防止美元“意外”转换为日元等 。Joda Money或timeandmoney就是两个这样的例子。
虽然 BigDecimal 在解决固定精度方面远优于双精度数,但它仍然不是正确的货币表示法 IMOHO。(BigDecimal 可能是后端 [或者它可以完全替换为另一个 impl。],作为前端,它不能充分代表域。)
快乐编码。
*正如其他人所说,这取决于使用情况。
我个人会坚持BigDecimal
。供应商使用双打有点令人不安,但是您没有理由传播他们的错误。您将从“稍微糟糕”的数据开始,但至少您不会在对这些值执行任何操作时引入更多意外行为。
您可能想与供应商交谈并了解他们为什么使用双打...
对此的猜测:
我注意到主要供应商的数据馈送 API 使用 double 类型来表示股票报价。有谁知道为什么?
当这样的 API 使用基于文本的格式(如 XML 或 JSON)时,传输的数据实际上不是双精度数,而是十进制数字 - 而十进制数字就是这里的意思。在某些 API 中,通常 double 是唯一支持十进制数(点后有数字)的数据类型。
当您收到双倍的股票价格并想“以金钱方式”计算它时,请确保您知道它有多少小数位(在点之后)(应该有 - 不是来自双倍,而是来自股票价格),然后用这个比例将它转换为 BigDecimal(或任何你用于货币计算的东西)。