Java 的 BigDecimal 是否像 C++ 中的 long double 那样利用硬件架构?

Does Java's BigDecimal leverage the hardware architecture like long double in C++?

据我了解,C++ 中的 long double 实际上利用了硬件架构(至少对于某些架构而言)。 Java 中的 BigDecimal 是否对足够小的输入执行此操作?

没有。 BigDecimal 不利用任何硬件架构。例如,参见 Java 源代码中 BigDecimal 的构造函数。

BigDecimal(BigInteger intVal, long val, int scale, int prec) {
    this.scale = scale;
    this.precision = prec;
    this.intCompact = val;
    this.intVal = intVal;
}

Does BigDecimal in Java do this for small enough inputs?

不,也不可能。浮点数是有损的,而每个 BigDecimal 都有一个关联的精度,并且可以精确表示低于该精度的任何数字。没有 "small enough input" 可以有用地呈现为浮点数,因为即使您碰巧有一个 BigDecimal 可以用浮点表示法精确表示的值,您也很难-按下以对该值执行任何类型的操作并保持指定的精度。

换句话说,BigDecimal 目的 是在牺牲速度的同时提供精度。这与浮点完全相反,浮点牺牲精度以提高速度。


听起来您是在问 Java 是否提供了一种处理 long double 大小的浮点数和 there is not 的方法。我们可以从事实中得出结论,这并不是说 JDK 作者从未觉得有必要添加到语言中。

BigDecimal 和典型的硬件 long double 支持之间最重要的区别是浮点基数。

BigDecimal 的值是一个整数乘以 10 的幂。浮点硬件通常基于 IEEE 二进制浮点,每个值都是整数乘以 2 的幂。

一些输入可以用 long double 精确表示的计算结果在 long double 中比在给定比例的 BigDecimal 中产生更大的舍入误差。例如,1 和 10 都可以用两种格式准确表示。 1 除以 10 的结果可以在 BigDecimal 中精确表示,比例至少为 1,但不能用任何基数 2 格式表示。

当然,有许多有理数无法用任何一种格式准确表示。考虑 1/3。即使在那里,BigDecimal 也会根据比例获得更大或更小的舍入误差。 long double 和 BigDecimal 的答案不太可能完全相同。

对每个计算进行测试以确定两种格式是否得到相同的答案会破坏使用硬件辅助带来的任何性能提升。