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

Dr. Hans-Peter Störr
  • 25,298
  • 30
  • 102
  • 139
  • A general question from a standpoint of interest... what is your application that requires several thousand of digits decimal precision? – Simon Nov 10 '08 at 09:27
  • 1
    This is a hobby, not a job: I'd like to calculate some more digits of the http://en.wikipedia.org/wiki/Feigenbaum_constant – Dr. Hans-Peter Störr Nov 11 '08 at 08:10

4 Answers4

40

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

Dr. Hans-Peter Störr
  • 25,298
  • 30
  • 102
  • 139
  • 2
    Do some of the libraries support trigonometric functions? –  Aug 08 '11 at 09:14
  • 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? – Asad Saeeduddin Mar 20 '15 at 00:54
  • @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. – Dr. Hans-Peter Störr Mar 22 '15 at 20:15
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.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • 1
    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. – Dr. Hans-Peter Störr Nov 08 '11 at 19:01
  • @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 :) – Jon Skeet Nov 08 '11 at 21:03
  • BigDecimal is fairly limited, for example it doesn't support sqrt in contrast to JScience – Tomasz Apr 27 '13 at 03:31
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.

Matt Passell
  • 4,549
  • 3
  • 24
  • 39
-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.

  • 1
    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. – Snickers Mar 04 '11 at 19:28
  • 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. –  Aug 08 '11 at 17:36