I’m looking for a good arbitrary precision math library in C or C++. Could you please give me some advices or suggestions?
The primary requirements:
It must handle arbitrarily big integers—my primary interest is on integers. In case that you don’t know what the word arbitrarily big means, imagine something like 100000! (the factorial of 100000).
The precision must not need to be specified during library initialization or object creation. The precision should only be constrained by the available resources of the system.
It should utilize the full power of the platform, and should handle “small” numbers natively. That means on a 64-bit platform, calculating (2^33 + 2^32) should use the available 64-bit CPU instructions. The library should not calculate this in the same way as it does with (2^66 + 2^65) on the same platform.
It must efficiently handle addition (+
), subtraction (-
), multiplication (*
), integer division (/
), remainder (%
), power (**
), increment (++
), decrement (--
), GCD, factorial, and other common integer arithmetic calculations. The ability to handle functions like square root and logarithm that do not produce integer results is a plus. The ability to handle symbolic computations is even better.
Here are what I found so far:
Java's BigInteger and BigDecimal class: I have been using these so far. I have read the source code, but I don’t understand the math underneath. It may be based on theories and algorithms that I have never learnt.
The built-in integer type or in core libraries of bc, Python, Ruby, Haskell, Lisp, Erlang, OCaml, PHP, some other languages: I have used some of these, but I have no idea which library they are using, or which kind of implementation they are using.
What I have already known:
Using char
for decimal digits and char*
for decimal strings, and do calculations on the digits using a for
-loop.
Using int
(or long int
, or long long
) as a basic “unit” and an array of that type as an arbitrary long integer, and do calculations on the elements using a for
-loop.
Using an integer type to store a decimal digit (or a few digits) as BCD (Binary-coded decimal).
Booth’s multiplication algorithm.
What I don’t know:
char*
-string mentioned above to store the intermediate decimal results).What I appreciate:
Good comparisons on GMP, MPFR, decNumber (or other libraries that are good in your opinion).
Good suggestions on books and articles that I should read. For example, an illustration with figures on how a non-naive binary-to-decimal conversion algorithm works would be good. The article “Binary to Decimal Conversion in Limited Precision” by Douglas W. Jones is an example of a good article.
Any help in general.
Please do not answer this question if you think that using double
(or long double
, or long long double
) can solve this problem easily. If you do think so, you don’t understand the issue in question.
GMP is the popular choice. Squeak Smalltalk has a very nice library, but it's written in Smalltalk.
You asked for relevant books or articles. The tricky part of bignums is long division. I recommend Per Brinch Hansen's paper Multiple-Length Division Revisited: A Tour of the Minefield.
Overall, he fastest general purpose arbitrary precision library is GMP. If you want to work with floating point values, look at the the MPFR library. MPFR is based on GMP.
Regarding native arbitrary precision support in other languages, Python uses its own implementation because of license, code size, and code portability reasons. The GMPY module lets Python access the GMP library.
See TTMath, a small templated header-only library free for personal and commercial use.
I've not compared arbitrary precision arithmetic libraries to each other myself, but people who do seem to have more or less uniformly settled on GMP. For what it's worth, the arbitrary precision integers in GHC Haskell and GNU Guile Scheme are both implemented using GMP, and the fastest implementation of the pidigits benchmark on the language shootout is based on GMP.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With