Java floating point high precision library [closed]
Asked Answered
A

4

23

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?

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).

Amphitryon answered 10/11, 2008 at 7:45 Comment(2)
A general question from a standpoint of interest... what is your application that requires several thousand of digits decimal precision?Multiped
This is a hobby, not a job: I'd like to calculate some more digits of the en.wikipedia.org/wiki/Feigenbaum_constantNest
A
41

There are three libraries mentioned on the Arbitrary Precision Arithmetic page: java.math (containing the mentioned BigDecimal), Apfloat and JScience. I run a little speed check on them which just uses addition and multiplication.

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.

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.

(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.)

Amphitryon answered 12/11, 2008 at 16:53 Comment(3)
Do some of the libraries support trigonometric functions?Balenciaga
Are you saying JScience maintains a constant ~4x speed advantage once you go over a certain threshold of digits? Or does the speed difference get more pronounced for more digits?Pendleton
@Asad I didn't do such detailed experiments, but I guess they use different algorithms with different time complexities. (At least for multiplication and so forth.) Thus the speed difference will get larger and larger the more digits you have. But if you want much more digits, you need to do your own experiments, and perhaps there are even better libraries for that.Nest
F
7

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.

Filefish answered 10/11, 2008 at 7:50 Comment(3)
For very high precision this is much slower. I'd only recommend this if you have only tens of digits or don't care about speed.Nest
@hstoerr: It's good that you've checked it - but I think the approach of "test the simplest thing that will work" (where being built in is a significant starting point advantage) is still a good initial step :)Filefish
BigDecimal is fairly limited, for example it doesn't support sqrt in contrast to JScienceEnuresis
S
3

You could take a look at the JScience library and their Real number 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.

Shayla answered 10/11, 2008 at 23:36 Comment(0)
W
-3

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.

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.

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... "

This appears to make Apfloat minimally useful.

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.

Weissmann answered 12/2, 2011 at 22:43 Comment(2)
Actually Phil, the reason for that pitfall is because you are constructing the Apfloat with a float or double. The inaccuracy is because you are passing it a number that is inaccurate. If you took the time to read the next paragraph, you would see that if you construct it with a string you can have infinite precision.Exam
BigDecimal 0.3 would be accurate. To take that example. Does Apfloat have a constructor from BigDecimal? BigDecimal is kind of a hybrid in representation, the mantissa is base 2 (BigInteger), but the exponent is base 10.Balenciaga

© 2022 - 2024 — McMap. All rights reserved.