2

让我首先说明对于我们正在开发的高性能应用程序类型,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++ 实现。

我一直无法找到任何关于其中一个的优点/缺点的讨论,没有任何特别的理由没有立即下降到“从不使用浮点数作为货币” - 如果性能不是主要的,我同意这个口头禅担心,但在这种情况下,我不太确定。

4

2 回答 2

0

我建议使用 along和 an intlong代表整数单位int的数量,代表十亿分之一的数量。这样的表示应该相当容易使用(特别是因为添加billionths两个数字的部分的结果不会溢出)并且大大优于任何一种比double.

于 2014-05-07T19:26:27.507 回答
0

我不确定这两种模式中的任何一种都可以被认为是我们工作领域的“最佳”模式。

好吧,您还没有提到域是什么,因此很难对此发表评论。

然而,许多与财务相关的系统都受一般会计规则的约束。这些都清楚地说明了应该如何进行财务计算,并且浮点是不可接受的。

如果您的域包含在会计规则中,那么使用浮点确实不是一种选择。

如果不是,那么您需要进行数学分析以确定浮点固有的不精确性是否会对计算结果产生影响。简单地使用更宽的浮点类型并不是一个好的答案……除非您已经“完成了数学运算”以对计算结果设置错误界限。

或者避免分析,只使用缩放longBigDecimal. (但请注意,缩放long时您需要考虑上溢/下溢的问题。)


如果您已经“完成了数学计算”并且您不受会计规则(或某些此类规则)的限制,那么:

  • 浮点类型将更易于使用,因为您在进行算术运算时不必弄乱比例因子。(即使比例因子是隐含的,也需要考虑在内……)

  • 浮点类型将“仅适用于”标准库方法;例如Math静态方法。

  • 浮点代码将更具可读性,并且不易出现编程逻辑错误。

  • 浮点类型是不精确的......但如果你正确地完成了数学运算,那就没关系了。(完整的数学分析将告诉您在计算过程中错误是否会累积到导致结果不准确的程度。)

性能……很难说。这可能取决于实际计算。我的建议是对关键计算进行双向编码并仔细对它们进行基准测试。

于 2013-02-13T13:47:08.967 回答