# Programming

## mpfr::real

### About

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
`double`

s 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::real`

s. 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::real`

s 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
`int`

s, 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`

).

### Download

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.

#### Download

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
`mpreal`

s 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::real`

s 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`

.)