让我首先说明对于我们正在开发的高性能应用程序类型,BigDecimal 的速度慢得令人无法接受。这不能妥协。
在我们的领域中,我们将以不同的精度表示高达 100,000,000 左右的值(在我们迄今为止发现的最深奥的情况下,这可能是小数点后六位)。
鉴于此,我看到了两种以任意精度表示货币信息的方法。第一种是遵循类似于JSR-354中描述的模式,其中 long 表示值的尾数,而 short(或 int)表示指数。在这种情况下,值 12345.6789 将在内部表示为
long mantissa = 123456789L;
short exponent = -4;
有了这个,我们可以以我们选择的任何精度表示 18 个数字(9223372036854775807 是 19 个数字)
第二种是使用 double 来表示值,并使用 epsilon 来舍入因对浮点数执行计算而引入的任何错误。根据我对每个计算机科学家应该了解的浮点运算知识和一些实验的理解,我相信我们可以以任何选择的精度表示 17 个数字。如果我们使用固定的 epsilon,我们可以按照我们预期的最多六位小数的要求表示高达 99999999999.999999 的值,我们的 epsilon 能够舍入任何引入的错误。
我不确定这两种模式中的任何一种都可以被认为是我们工作领域的“最佳”模式。
如果我们需要对两个具有不同精度的值执行操作(这将是必需的),多/空模式需要我们实现一些位置移动逻辑。我认为,但尚未证实,这将使它比在某些操作中使用 double/epsilon 慢。另一方面,使用 double/epsilon 会在每次计算中引入少量开销来执行舍入。
如果需要,两者都可以扩展以提供更多位数 - JSR-354 提到了一个 long/long/int 实现,它以任意精度提供多达 37 位数字。本文描述了 double-double 和 quad-double 类型的 C++ 实现。
我一直无法找到任何关于其中一个的优点/缺点的讨论,没有任何特别的理由没有立即下降到“从不使用浮点数作为货币” - 如果性能不是主要的,我同意这个口头禅担心,但在这种情况下,我不太确定。