java Java浮点高精度库
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/277309/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Java floating point high precision library
提问by Hans-Peter St?rr
Which libraries for Java are there that have a fast implementation for floating point or fixed point operations with a precision of several thousands of digits? How performant are they?
有哪些 Java 库可以快速实现精度为数千位的浮点或定点运算?它们的性能如何?
A requirement for me is that it implements a multiplication algorithm that is better than the naive multiplication algorithm that takes 4 times as much time for a 2 times larger number of digits (compare Multiplication algorithms).
对我的要求是它实现了一种比朴素的乘法算法更好的乘法算法,后者需要 4 倍的时间来处理 2 倍大的数字(比较乘法算法)。
回答by Hans-Peter St?rr
There are three libraries mentioned on the Arbitrary Precision Arithmeticpage: java.math (containing the mentioned BigDecimal), Apfloatand JScience. I run a little speed check on them which just uses addition and multiplication.
Arbitrary Precision Arithmetic页面上提到了三个库: java.math (包含提到的 BigDecimal)、Apfloat和JScience。我对它们进行了一些速度检查,只使用加法和乘法。
The result is that for a relatively small number of digits BigDecimal is OK (half as fast as the others for 1000 digits), but if you use more digits it is way off - JScience is about 4 times faster. But the clear performance winner is Apfloat. The other libraries seem to use naive multiplication algorithms that take time proportional to the square of the number of digits, but the time of Apfloat seems to grow almost linearly. On 10000 digits it was 4 times as fast as JScience, but on 40000 digits it is 16 times as fast as JScience.
结果是,对于相对较少的数字,BigDecimal 是可以的(对于 1000 位数字是其他数字的一半),但是如果您使用更多数字,那就太远了 - JScience 大约快 4 倍。但明显的性能赢家是 Apfloat。其他库似乎使用朴素的乘法算法,其时间与位数的平方成正比,但 Apfloat 的时间似乎几乎呈线性增长。在 10000 位数上,它是 JScience 的 4 倍,但在 40000 位数上,它是 JScience 的 16 倍。
On the other hand: JScience provides EXCELLENT functionality for mathematical problems: matrices, vectors, symbolic algorithms, solution of equation systems and what not. So I'll probably go with JScience and later write a wrapper to integrate Apfloat into the algorithms of JScience - due to the good design this seems easily possible.
另一方面:JScience 为数学问题提供了优秀的功能:矩阵、向量、符号算法、方程组的求解等等。所以我可能会选择 JScience,然后编写一个包装器将 Apfloat 集成到 JScience 的算法中 - 由于设计良好,这似乎很容易实现。
(UPDATE: I wrote a test suite for the number package of JScience and fixed a number of bugs. This went into release 4.3.1. So I can recommend checking it out.)
(更新:我为 JScience 的 number 包编写了一个测试套件并修复了一些错误。这进入了 4.3.1 版。所以我可以建议检查一下。)
回答by Jon Skeet
Have you checked the performance of BigDecimal? I can't see anything obvious in the JavaDoc, but it would certainly be my first port of call.
您是否检查过BigDecimal的性能?我在 JavaDoc 中看不到任何明显的东西,但它肯定是我的第一个停靠港。
回答by Matt Passell
You could take a look at the JSciencelibrary and their Realnumber class. I'm not sure how the performance is relative to BigDecimal, but the goal of the library is to provide highly-tuned classes for scientific applications, which seems like a good sign.
您可以查看JScience库和它们的Realnumber 类。我不确定相对于 BigDecimal 的性能如何,但该库的目标是为科学应用程序提供高度优化的类,这似乎是一个好兆头。
回答by Phil Goetz
Apfloat offers high precision on the mantissa, but appears to give less-than-usual precision on the exponent (based on the fact that it crashes with "Logarithm of zero" for values that double can handle). So it is not useful for big numbers.
Apfloat 在尾数上提供了高精度,但似乎在指数上提供了低于通常的精度(基于它与 double 可以处理的值的“零对数”崩溃的事实)。所以它对大数字没有用。
Also, the documentation says:
此外,文档说:
"A pitfall exists with the constructors Apfloat(float,long) and Apfloat(double,long). Since floats and doubles are always represented internally in radix 2, the conversion to any other radix usually causes round-off errors, and the resulting apfloat won't be accurate to the desired number of digits.
“构造函数 Apfloat(float,long) 和 Apfloat(double,long) 存在缺陷。由于浮点数和双精度数总是在基数 2 内部表示,因此转换为任何其他基数通常会导致舍入错误,并且由此产生的 apfloat不会准确到所需的位数。
For example, 0.3 can't be presented exactly in base 2. When you construct an apfloat like new Apfloat(0.3f, 1000), the resulting number won't be accurate to 1000 digits, but only to roughly 7 digits (in radix 10). In fact, the resulting number will be something like 0.30000001192092896... "
例如,0.3 不能精确地以基数 2 表示。当您构造像 new Apfloat(0.3f, 1000) 这样的 apfloat 时,结果数字不会精确到 1000 位,而只能精确到大约 7 位(以基数为基础) 10)。事实上,结果数字将类似于 0.30000001192092896...”
This appears to make Apfloat minimally useful.
这似乎使 Apfloat 的用处很小。
BigDecimal does not have a logarithm function, and the documentation does not say whether it allows you to make bigger numbers than a double; the exponent is 32 bits, sort of.
BigDecimal 没有对数函数,文档也没有说明它是否允许您生成比 double 更大的数字;指数是 32 位,有点。

