在Java货币表示中,与双尾数/ε模式相比,使用长/短尾数/指数模式的优缺点是什么

在Java货币表示中,与双尾数/ε模式相比,使用长/短尾数/指数模式的优缺点是什么,java,floating-point,currency,Java,Floating Point,Currency,让我首先说明,对于我们正在开发的高性能应用程序类型,BigDecimal的速度慢得令人无法接受。这是不能妥协的 在我们的领域中,我们将以不同的精度表示高达100000000左右的值(在迄今为止我们发现的最深奥的情况下,这可能是小数点后六位) 鉴于此,我看到了两种以任意精度表示货币信息的方法。第一种是遵循类似于中描述的模式,其中长表示值的尾数,短(或int)表示指数。在这种情况下,12345.6789的值在内部表示为 long mantissa = 123456789L; short expone

让我首先说明,对于我们正在开发的高性能应用程序类型,BigDecimal的速度慢得令人无法接受。这是不能妥协的

在我们的领域中,我们将以不同的精度表示高达100000000左右的值(在迄今为止我们发现的最深奥的情况下,这可能是小数点后六位)

鉴于此,我看到了两种以任意精度表示货币信息的方法。第一种是遵循类似于中描述的模式,其中长表示值的尾数,短(或int)表示指数。在这种情况下,12345.6789的值在内部表示为

long mantissa = 123456789L;
short exponent = -4;
有了这个,我们可以以任意精度表示18个数字(9223372036854775807为19个数字)

第二种方法是使用double来表示值,并使用epsilon来舍入通过对浮点数执行计算而引入的任何错误。基于我的理解和一些实验,我相信我们可以以任意精度表示17个数字。如果我们使用一个固定的epsilon,我们可以在预期的最大小数点后六位的要求下表示高达99999999.9999999的值,并且我们的epsilon能够舍入引入的任何错误


我不确定这两种模式中的任何一种对于我们正在工作的领域来说都是“最好的”

如果我们需要以不同的精度对两个值执行操作,长/短模式要求我们实现一些位置移动逻辑(这是必需的)。我认为,但尚未证实,这将使它比在某些操作中使用double/epsilon更慢。另一方面,使用double/epsilon在执行舍入的每次计算中引入了少量开销

如果需要,两者都可以扩展以提供更大数量的数字-JSR-354提到了一个long/long/int实现,它以任意精度提供最多37个数字。描述了双双四重型的C++实现。 我找不到任何关于另一种方法的优缺点的讨论,没有任何特别的理由就没有立即演变为“永远不要使用浮点货币”——如果性能不是主要问题,我同意这一说法,但在这种情况下,我不太确定

我不确定这两种模式中的任何一种对于我们正在工作的领域来说都是“最好的”

你没有提到域名是什么,所以很难对此发表评论

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

如果您的域包含在会计规则中,那么使用浮点实际上不是一个选项

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

或者避免分析,只需使用缩放的
long
BigDecimal
。(但请注意,在缩放<代码>长您需要考虑溢出/下溢的问题)


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

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

  • 浮点类型将使用标准库方法“正常工作”;e、 g.
    数学
    静态方法

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

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


表演。。。很难说。这可能取决于实际计算。我的建议是对关键计算进行双向编码,并仔细地对其进行基准测试。

我建议使用
long
int
,其中
long
表示整个单位的数量,
int
表示十亿分之一的数量。这样的表示应该相当容易使用(特别是因为两个数字的
十亿分之一
部分相加的结果不会溢出),并且远远优于任何一种浮点表示,而不是域中的
双精度

“精确表示和计算高达100000000的数字,精确到小数点后6位”。我不确定我们如何处理这些数字是否重要,尽管在这种情况下是对金融工具的价值计算。我们不受任何会计规则的约束。我已经“完成了数学计算”“。长/整数和双精度/ε都包含所需的值和精度范围。如第一句所述,BigDecimal对于任务来说速度慢得令人无法接受。我在寻找这两种解决方案的优缺点,这两种方案都能奏效。你对小数点后六位永远足够有多大信心?如果您非常自信,您是否考虑过通过将所有项移动一个因子
10^6
,来去除内部计算的指数?也就是说,你处理的不是123.456789美元,而是123456789美元。我不确定这是否合适