Next: , Previous: Reporting Bugs, Up: Top


4 MPFR Basics

4.1 Headers and Libraries

All declarations needed to use MPFR are collected in the include file mpfr.h. It is designed to work with both C and C++ compilers. You should include that file in any program using the MPFR library:

     #include <mpfr.h>

Note however that prototypes for MPFR functions with FILE * parameters are provided only if <stdio.h> is included too (before mpfr.h).

     #include <stdio.h>
     #include <mpfr.h>

Likewise <stdarg.h> (or <varargs.h>) is required for prototypes with va_list parameters, such as mpfr_vprintf.

You can avoid the use of MPFR macros encapsulating functions by defining the ‘MPFR_USE_NO_MACRO’ macro before mpfr.h is included. In general this should not be necessary, but this can be useful when debugging user code: with some macros, the compiler may emit spurious warnings with some warning options, and macros can prevent some prototype checking.

All programs using MPFR must link against both libmpfr and libgmp libraries. On a typical Unix-like system this can be done with ‘-lmpfr -lgmp’ (in that order), for example

     gcc myprogram.c -lmpfr -lgmp

MPFR is built using Libtool and an application can use that to link if desired, see GNU Libtool.

If MPFR has been installed to a non-standard location, then it may be necessary to set up environment variables such as ‘C_INCLUDE_PATH’ and ‘LIBRARY_PATH’, or use ‘-I’ and ‘-L’ compiler options, in order to point to the right directories. For a shared library, it may also be necessary to set up some sort of run-time library path (e.g., ‘LD_LIBRARY_PATH’) on some systems. Please read the INSTALL file for additional information.

4.2 Nomenclature and Types

A floating-point number or float for short, is an arbitrary precision significand (also called mantissa) with a limited precision exponent. The C data type for such objects is mpfr_t (internally defined as a one-element array of a structure, and mpfr_ptr is the C data type representing a pointer to this structure). A floating-point number can have three special values: Not-a-Number (NaN) or plus or minus Infinity. NaN represents an uninitialized object, the result of an invalid operation (like 0 divided by 0), or a value that cannot be determined (like +Infinity minus +Infinity). Moreover, like in the IEEE 754-1985 standard, zero is signed, i.e. there are both +0 and −0; the behavior is the same as in the IEEE 754-1985 standard and it is generalized to the other functions supported by MPFR.

The precision is the number of bits used to represent the significand of a floating-point number; the corresponding C data type is mp_prec_t. The precision can be any integer between MPFR_PREC_MIN and MPFR_PREC_MAX. In the current implementation, MPFR_PREC_MIN is equal to 2.

Warning! MPFR needs to increase the precision internally, in order to provide accurate results (and in particular, correct rounding). Do not attempt to set the precision to any value near MPFR_PREC_MAX, otherwise MPFR will abort due to an assertion failure. Moreover, you may reach some memory limit on your platform, in which case the program may abort, crash or have undefined behavior (depending on your C implementation).

The rounding mode specifies the way to round the result of a floating-point operation, in case the exact result can not be represented exactly in the destination significand; the corresponding C data type is mp_rnd_t.

A limb means the part of a multi-precision number that fits in a single word. (We chose this word because a limb of the human body is analogous to a digit, only larger, and containing several digits.) Normally a limb contains 32 or 64 bits. The C data type for a limb is mp_limb_t.

4.3 Function Classes

There is only one class of functions in the MPFR library:

  1. Functions for floating-point arithmetic, with names beginning with mpfr_. The associated type is mpfr_t.

4.4 MPFR Variable Conventions

As a general rule, all MPFR functions expect output arguments before input arguments. This notation is based on an analogy with the assignment operator.

MPFR allows you to use the same variable for both input and output in the same expression. For example, the main function for floating-point multiplication, mpfr_mul, can be used like this: mpfr_mul (x, x, x, rnd_mode). This computes the square of x with rounding mode rnd_mode and puts the result back in x.

Before you can assign to an MPFR variable, you need to initialize it by calling one of the special initialization functions. When you're done with a variable, you need to clear it out, using one of the functions for that purpose.

A variable should only be initialized once, or at least cleared out between each initialization. After a variable has been initialized, it may be assigned to any number of times.

For efficiency reasons, avoid to initialize and clear out a variable in loops. Instead, initialize it before entering the loop, and clear it out after the loop has exited.

You do not need to be concerned about allocating additional space for MPFR variables, since any variable has a significand of fixed size. Hence unless you change its precision, or clear and reinitialize it, a floating-point variable will have the same allocated space during all its life.

4.5 Rounding Modes

The following four rounding modes are supported:

The ‘round to nearest’ mode works as in the IEEE 754-1985 standard: in case the number to be rounded lies exactly in the middle of two representable numbers, it is rounded to the one with the least significant bit set to zero. For example, the number 5/2, which is represented by (10.1) in binary, is rounded to (10.0)=2 with a precision of two bits, and not to (11.0)=3. This rule avoids the drift phenomenon mentioned by Knuth in volume 2 of The Art of Computer Programming (Section 4.2.2).

Most MPFR functions take as first argument the destination variable, as second and following arguments the input variables, as last argument a rounding mode, and have a return value of type int, called the ternary value. The value stored in the destination variable is correctly rounded, i.e. MPFR behaves as if it computed the result with an infinite precision, then rounded it to the precision of this variable. The input variables are regarded as exact (in particular, their precision does not affect the result).

As a consequence, in case of a non-zero real rounded result, the error on the result is less or equal to 1/2 ulp (unit in the last place) of the target in the rounding to nearest mode, and less than 1 ulp of the target in the directed rounding modes (a ulp is the weight of the least significant represented bit of the target after rounding).

Unless documented otherwise, functions returning an int return a ternary value. If the ternary value is zero, it means that the value stored in the destination variable is the exact result of the corresponding mathematical function. If the ternary value is positive (resp. negative), it means the value stored in the destination variable is greater (resp. lower) than the exact result. For example with the GMP_RNDU rounding mode, the ternary value is usually positive, except when the result is exact, in which case it is zero. In the case of an infinite result, it is considered as inexact when it was obtained by overflow, and exact otherwise. A NaN result (Not-a-Number) always corresponds to an exact return value. The opposite of a returned ternary value is guaranteed to be representable in an int.

Unless documented otherwise, functions returning a 1 (or any other value specified in this manual) for special cases (like acos(0)) should return an overflow or an underflow if 1 is not representable in the current exponent range.

4.6 Floating-Point Values on Special Numbers

This section specifies the floating-point values (of type mpfr_t) returned by MPFR functions. For functions returning several values (like mpfr_sin_cos), the rules apply to each result separately.

Functions can have one or several input arguments. An input point is a mapping from these input arguments to the set of the MPFR numbers. When none of its components are NaN, an input point can also be seen as a tuple in the extended real numbers (the set of the real numbers with both infinities).

When the input point is in the domain of the mathematical function, the result is rounded as described in Section “Rounding Modes” (but see below for the specification of the sign of an exact zero). Otherwise the general rules from this section apply unless stated otherwise in the description of the MPFR function (MPFR Interface).

When the input point is not in the domain of the mathematical function but is in its closure in the extended real numbers and the function can be extended by continuity, the result is the obtained limit. Examples: mpfr_hypot on (+Inf,0) gives +Inf. But mpfr_pow cannot be defined on (1,+Inf) using this rule, as one can find sequences (x_n,y_n) such that x_n goes to 1, y_n goes to +Inf and x_n to the y_n goes to any positive value when n goes to the infinity.

When the input point is in the closure of the domain of the mathematical function and an input argument is +0 (resp. −0), one considers the limit when the corresponding argument approaches 0 from above (resp. below). If the limit is not defined (e.g., mpfr_log on −0), the behavior must be specified in the description of the MPFR function.

When the result is equal to 0, its sign is determined by considering the limit as if the input point were not in the domain: If one approaches 0 from above (resp. below), the result is +0 (resp. −0). In the other cases, the sign must be specified in the description of the MPFR function. Example: mpfr_sin on +0 gives +0.

When the input point is not in the closure of the domain of the function, the result is NaN. Example: mpfr_sqrt on −17 gives NaN.

When an input argument is NaN, the result is NaN, possibly except when a partial function is constant on the finite floating-point numbers; such a case is always explicitly specified in MPFR Interface. Example: mpfr_hypot on (NaN,0) gives NaN, but mpfr_hypot on (NaN,+Inf) gives +Inf (as specified in Special Functions), since for any finite input x, mpfr_hypot on (x,+Inf) gives +Inf.

4.7 Exceptions

MPFR supports 5 exception types:

MPFR has a global flag for each exception, which can be cleared, set or tested by functions described in Exception Related Functions.

Differences with the ISO C99 standard:

4.8 Memory Handling

MPFR functions may create caches, e.g. when computing constants such as Pi, either because the user has called a function like mpfr_const_pi directly or because such a function was called internally by the MPFR library itself to compute some other function.

At any time, the user can free the various caches with mpfr_free_cache. It is strongly advised to do that before terminating a thread, or before exiting when using tools like ‘valgrind’ (to avoid memory leaks being reported).

MPFR internal data such as flags, the exponent range, the default precision and rounding mode, and caches (i.e., data that are not accessed via parameters) are either global (if MPFR has not been compiled as thread safe) or per-thread (thread local storage).