有哪些 Java 库可以快速实现精度为数千位的浮点或定点运算?它们的性能如何?
对我的一个要求是它实现了一种乘法算法,该算法优于简单乘法算法,该算法需要 4 倍的时间来获得 2 倍大的数字(比较乘法算法)。
有哪些 Java 库可以快速实现精度为数千位的浮点或定点运算?它们的性能如何?
对我的一个要求是它实现了一种乘法算法,该算法优于简单乘法算法,该算法需要 4 倍的时间来获得 2 倍大的数字(比较乘法算法)。
Arbitrary Precision Arithmetic页面上提到了三个库:java.math(包含提到的 BigDecimal)、Apfloat和JScience。我对它们进行了一点速度检查,它只使用加法和乘法。
结果是,对于相对较少的数字,BigDecimal 是可以的(对于 1000 位数字,它的速度是其他数字的一半),但是如果您使用更多的数字,那就太差了 - JScience 大约快 4 倍。但明显的性能赢家是 Apfloat。其他库似乎使用天真的乘法算法,其时间与位数的平方成正比,但 Apfloat 的时间似乎几乎呈线性增长。在 10000 位上,它是 JScience 的 4 倍,但在 40000 位上,它是 JScience 的 16 倍。
另一方面:JScience 为数学问题提供了出色的功能:矩阵、向量、符号算法、方程系统的解等等。所以我可能会选择 JScience,然后编写一个包装器来将 Apfloat 集成到 JScience 的算法中——由于良好的设计,这似乎很容易实现。
(更新:我为 JScience 的 number 包编写了一个测试套件并修复了一些错误。这进入了 4.3.1 版。所以我可以建议检查一下。)
你检查过BigDecimal的性能吗?我在 JavaDoc 中看不到任何明显的东西,但它肯定是我的第一个停靠港。
Apfloat 在尾数上提供高精度,但在指数上的精度似乎低于通常的精度(基于它与 double 可以处理的值的“零对数”崩溃的事实)。所以它对大数字没有用。
此外,文档说:
“构造函数 Apfloat(float,long) 和 Apfloat(double,long) 存在一个陷阱。由于浮点数和双精度数始终在内部以基数 2 表示,因此转换为任何其他基数通常会导致舍入错误,并且生成的 apfloat不会准确到所需的位数。
例如,0.3 不能精确地以 2 为底。当你构造一个像 new Apfloat(0.3f, 1000) 这样的 apfloat 时,得到的数字不会精确到 1000 位,而只能精确到大约 7 位(以基数为单位) 10)。实际上,结果数字将类似于 0.30000001192092896..."
这似乎使 Apfloat 的用处最小。
BigDecimal 没有对数函数,文档也没有说明它是否允许您制作比双精度更大的数字;指数是32位,有点。