Programming

mpfr::real

The class mpfr::real is a high-level C++ wrapper for the GNU MPFR library, “a C library for multiple-precision floating-point computations with correct rounding”.

The objects of mpfr::real can (almost) be used like doubles or other fundamental floating-point types, thus avoiding the use of C functions to manipulate MPFR's low-level data type directly. In addition to all arithmetic and comparison operators available for fundamental floating-point types, mpfr::real also supports the set of mathematical functions for double from math.h/cmath. Finally, std::istream operator >> and std::ostream operator << are implemented for mpfr::reals. This allows to substitute double with mpfr::real with no further modifications of the code in many cases.

Example

The following shows an example of how to use mpfr::real.

File: example.cpp

#include "real.hpp"

int main () {
mpfr::real<4096> a = "1.23456789";
mpfr::real<4096> b = 5.;
std::cout << sin(2 * pow(a, b)) << std::endl;

return 0;
}

The calculation is done with mpfr::reals with 4096 bits of precision (see the template argument of mpfr::real). The rounding used in the calculation defaults to MPFR_RNDN. An alternative rounding supported by the MPFR library could have been set as second template argument of mpfr::real.

The variable a is initialized from the char[] "1.23456789". If the quotation marks had been omitted, the token 1.23456789 would have been interpreted as double and a would have been initialized from that double. This would have been resulted in a truncation of precision of the number 1.23456789 to the precision of a double (e.g., 53 bits) and there would have been a loss of precision in the initialization of a.

The variable b is initialized from the double 5., which has an exact representation. Hence, there is no loss in precision. The last line calculates a to the power of b, multiplies it with the int 2 using the optimized multiplication function of MPFR's data type with ints, and calculates the sine of the result. The result type of the whole calculation is a mpfr::real<4096>, which is finally output (with the configured precision of std::cout).

Although some testing has been done, mpfr::real is still alpha software and may contain serious errors. If you experience problems, please drop me a mail.

Brian Gladman pointed out several problems with Microsoft Visual C++. Temporarily, there will be two different headers for G++ and Visual C++. I aim at publishing a new, single version with extended documentation that will work with all major compiler soon. Make sure you pick the right one.

The current package includes the header file real.hpp which is the only file neccessary for using mpfr::real, a README file, test programs etc.:

It is published under the terms of the GNU GPL v3 (see http://www.gnu.org/licenses/). It requires the GNU MPFR library version 3.0.0 or later.

Comparison with Other MPFR C++ Wrappers

There are already some C++ wrappers for the MPFR library, most notably Pavel Holoborodko's MPFR C++ package, which provides the class mpreal with a very similar functionality as mpfr::real. The main differences between mpreal and mpfr::real are due to different design decisions:

The class mpfr::real is a template class with two template parameters: The first one is an integer specifying the precision (in bits) and the second one is the rounding used by the MPFR library (defaults to MPFR_RNDN). Hence, each mpfr::real with different precision and/or rounding effectively constitutes a new data type. As a result, the precision of a mpfr::real must be known during compile time and cannot be changed or set during runtime. In contrast, mpreal is not a template class and the precision as well as the rounding of mpreals can be changes during runtime.

However, the use of template metaprogramming techniques in mpfr::real provides some advantages: Firstly, they allow for optimizing away the C++ class overhead during compile time such that the generated code is basically identical to the code that would have been generated when using the MPFR C interface. Secondly, it allows for fine-tuning the support of other data types (implicit/explicit type conversion, enabling/disabling of operators or mathematical functions, etc.) in mpfr::real by use of type traits. This includes the handling of mpfr::reals with different precision in the same expression.

Last but not least, mpfr::real provides the complete set of mathematical functions as known from math.h/cmath, which might be useful in some cases. (Still, the “typical” functions are also supported by mpreal.)