Apfloat
A high-performance C++ arbitrary precision library
by Mikko Tommila
Apfloat was originally designed only for calculating millions of digits of pi.
By now Apfloat is also a general-purpose arbitrary precision library which is
designed for ease of use and very high performance. All the standard C math
library functions and C++ complex math library functions are overloaded for the
arbitrary precision floating-point data type, apfloat.
Apfloat uses Fast Number Theoretic Transforms for calculating the convolution of
the long multiplications. Thus there cannot be any round-off errors in the
calculation of the convolution, like in normal complex FFTs which are calculated
with floating-point approximations.
Also, when using the Number Theoretic Transform, one can use memory quite
optimally. When doing Nubmer Theoretic Transforms, the result of the
convolution is only calculated modulo the modulus. Thus the result can easily
overflow the modulus, when the base (like 10^9) is close to the modulus (say,
about 2^31). The elements in the result of the convolution can be as large as
(base)^2*(transform length). When doing a normal complex floating-point FFT, the
result must not overflow, since then the least significant bits would be
permanently lost and the result of the convolution would be incorrect. So the
base must be chosen to be small enough, and thus the number of digits that can
fit in memory is quite limited. If the FFT is done using disk storage as
temporary space, it will be slowed down a lot.
But when doing a Number Theoretic Transform, one can do the transform modulo
three different moduli, not care about overflows, and get the final result from
the three convoluted sequences modulo the *product* of the moduli using the
Chinese Remainder Theorem. Thus one can fit much more digits of a number in
memory, do three separate transforms, and only do one linear pass through the
data that is stored temporarily on disk.
To put it short, Number Theoretic Transforms are somewhat slower than complex
floating-point FFTs, but enable one to do a lot longer thransforms.
The Fast Number Theoretic Transforms are calculated using the "Four-step"
algorithm, or actually the "Six-step" algorithm. It improves performance greatly
on computers with a cache memory (that is, practically all modern computers),
since it does the transform in small blocks, and thus almost all memory accesses
are cache hits. When memory runs out apfloat has a "Two-pass" disk transform
algorithm, which only does two passes through the data on disk, regardless of
the transform size. In theory this is quite optimal, but in practice it is so
slow, that it's useless. So, for practical calculations the transform must fit
entirely in memory.
Apfloat has assembler optimizations for some of the most popular processors
today for maximum performance. With extreme assembler hand-tuning, performance
for example on the Intel Pentium can be increased almost by a factor of 4.
Apfloat stores numbers either on disk or in memory, depending on the size of the
number and the amount of available memory. This gives a good compromise of speed
and capacity that is totally invisible to the user.
Use of apfloat has been made as simple as possible. C++ makes it possible to
overload all the usual arithmetic operations and mathematical functions for the
apfloat and apcomplex data types. Writing code to use the apfloat package is as
simple as writing normal C code, you only have to specify the precision with
which the numbers are calculated. The complicated and optimized inner functions
of apfloat are invisible to the end user, although fine-tuning of the parameters
is possible, if one wants to do so.
Apfloat is designed for extremely large precision, that is at least several
thousand digits. There is no point in calculating pi to, say, 200 decimals with
apfloat, since the round-off error can be 50 digits. This is no problem, of
course, when you calculate ten million digits of pi.
There is a much detailed description of the whole package in the actual
documentation, which is available in digital form on the CD along the package
itself.