Constant gmp_mpfr_sys::C::MPFR::MPFR_Basics [−][src]
pub const MPFR_Basics: ();
This constant is a place-holder for documentation; do not use it in code.
Next: MPFR Interface, Previous: Reporting Bugs, Up: Top [Index]
4 MPFR Basics
Next: Nomenclature and Types, Previous: MPFR Basics, Up: MPFR Basics [Index]
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
.
And for any functions using intmax_t
, you must include
<stdint.h>
or <inttypes.h>
before mpfr.h, to
allow mpfr.h to define prototypes for these functions.
Moreover, under some platforms (in particular with C++ compilers),
users may need to define
MPFR_USE_INTMAX_T
(and should do it for portability) before
mpfr.h has been included; of course, it is possible to do that
on the command line, e.g., with -DMPFR_USE_INTMAX_T
.
Note: If mpfr.h and/or gmp.h (used by mpfr.h)
are included several times (possibly from another header file),
<stdio.h>
and/or <stdarg.h>
(or <varargs.h>
)
should be included before the first inclusion of
mpfr.h or gmp.h. Alternatively, you can define
MPFR_USE_FILE
(for MPFR I/O functions) and/or
MPFR_USE_VA_LIST
(for MPFR functions with va_list
parameters) anywhere before the last inclusion of mpfr.h.
As a consequence, if your file is a public header that includes
mpfr.h, you need to use the latter method.
When calling a MPFR macro, it is not allowed to have previously defined
a macro with the same name as some keywords (currently do
,
while
and sizeof
).
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.
Alternatively, it is possible to use ‘pkg-config’ (a file ‘mpfr.pc’ is provided as of MPFR 4.0):
cc myprogram.c $(pkg-config --cflags --libs mpfr)
Note that the ‘MPFR_’ and ‘mpfr_’ prefixes are reserved for MPFR. As a general rule, in order to avoid clashes, software using MPFR (directly or indirectly) and system headers/libraries should not define macros and symbols using these prefixes.
Next: MPFR Variable Conventions, Previous: Headers and Libraries, Up: MPFR Basics [Index]
4.2 Nomenclature and Types
A floating-point number, or float for short, is an object representing a radix-2 floating-point number consisting of a sign, an arbitrary-precision normalized significand (also called mantissa), and an exponent (an integer in some given range); these are called regular numbers. Like in the IEEE 754 standard, a floating-point number can also have three kinds of special values: a signed zero, a signed infinity, and Not-a-Number (NaN). NaN can represent the default value of a floating-point object and the result of some operations for which no other results would make sense, such as 0 divided by 0 or +Infinity minus +Infinity; unless documented otherwise, the sign bit of a NaN is unspecified. Note that contrary to IEEE 754, MPFR has a single kind of NaN and does not have subnormals. Other than that, the behavior is very similar to IEEE 754, but there may be some differences.
The C data type for such objects is mpfr_t
, internally defined
as a one-element array of a structure (so that when passed as an
argument to a function, it is the pointer that is actually passed),
and mpfr_ptr
is the C data type representing a pointer to this
structure.
The precision is the number of bits used to represent the significand
of a floating-point number;
the corresponding C data type is mpfr_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 1.
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. However, in practice,
the real limitation will probably be the available memory on your platform,
and in case of lack of memory, the program may abort, crash or have
undefined behavior (depending on your C implementation).
An exponent is a component of a regular floating-point number.
Its C data type is mpfr_exp_t
. Valid exponents are restricted
to a subset of this type, and the exponent range can be changed globally
as described in Exception Related Functions. Special values do not
have an exponent.
The rounding mode specifies the way to round the result of a
floating-point operation, in case the exact result cannot be represented
exactly in the destination (see Rounding).
The corresponding C data type is mpfr_rnd_t
.
MPFR has a global (or per-thread) flag for each supported exception and provides operations on flags (Exceptions). This C data type is used to represent a group of flags (or a mask).
Next: Rounding, Previous: Nomenclature and Types, Up: MPFR Basics [Index]
4.3 MPFR Variable Conventions
Before you can assign to a MPFR variable, you need to initialize it by calling one of the special initialization functions. When you are 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.
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)
.
This computes the square of x with rounding mode rnd
and puts the result back in x.
Next: Floating-Point Values on Special Numbers, Previous: MPFR Variable Conventions, Up: MPFR Basics [Index]
4.4 Rounding
The following rounding modes are supported:
-
MPFR_RNDN
: round to nearest, with the even rounding rule (roundTiesToEven in IEEE 754-2008); see details below. -
MPFR_RNDD
: round toward minus infinity (roundTowardNegative in IEEE 754-2008). -
MPFR_RNDU
: round toward plus infinity (roundTowardPositive in IEEE 754-2008). -
MPFR_RNDZ
: round toward zero (roundTowardZero in IEEE 754-2008). -
MPFR_RNDA
: round away from zero. -
MPFR_RNDF
: faithful rounding. This feature is currently experimental. Specific support for this rounding mode has been added to some functions, such as the basic operations (addition, subtraction, multiplication, square, division, square root) or when explicitly documented. It might also work with other functions, as it is possible that they do not need modification in their code; even though a correct behavior is not guaranteed yet (corrections were done when failures occurred in the test suite, but almost nothing has been checked manually), failures should be regarded as bugs and reported, so that they can be fixed.
Note that, in particular for a result equal to zero, the sign is preserved by the rounding operation.
The MPFR_RNDN
mode works like roundTiesToEven from the
IEEE 754 standard: in case the number to be rounded lies exactly
in the middle between two consecutive representable numbers, it is
rounded to the one with an even significand; in radix 2, this means
that the least significant bit is 0. For example, the number 2.5,
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).
Note: In particular for a 1-digit precision (in radix 2 or other radices, as in conversions to a string of digits), one considers the significands associated with the exponent of the number to be rounded. For instance, to round the number 95 in radix 10 with a 1-digit precision, one considers its truncated 1-digit integer significand 9 and the following integer 10 (since these are consecutive integers, exactly one of them is even). 10 is the even significand, so that 95 will be rounded to 100, not to 90.
For the directed rounding modes, a number x is rounded to the number y that is the closest to x such that
-
MPFR_RNDD
: y is less than or equal to x; -
MPFR_RNDU
: y is greater than or equal to x; -
MPFR_RNDZ
: abs(y) is less than or equal to abs(x); -
MPFR_RNDA
: abs(y) is greater than or equal to abs(x).
The MPFR_RNDF
mode works as follows: the computed value is either
that corresponding to MPFR_RNDD
or that corresponding to
MPFR_RNDU
.
In particular when those values are identical,
i.e., when the result of the corresponding operation is exactly
representable, that exact result is returned.
Thus, the computed result can take at most two possible values, and
in absence of underflow/overflow, the corresponding error is strictly
less than one ulp (unit in the last place) of that result and of the
exact result.
For MPFR_RNDF
, the ternary value (defined below) and the inexact flag
(defined later, as with the other flags) are unspecified, the divide-by-zero
flag is as with other roundings, and the underflow and overflow flags match
what would be obtained in the case the computed value is the same as with
MPFR_RNDD
or MPFR_RNDU
.
The results may not be reproducible.
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 than or equal to 1/2 ulp (unit in the last place) of that result in the rounding to nearest mode, and less than 1 ulp of that result in the directed rounding modes (a ulp is the weight of the least significant represented bit of the result 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 MPFR_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 as result the value 1
(or any other value specified in this manual)
for special cases (like acos(0)
) yield an overflow or
an underflow if that value is not representable in the current exponent range.
Next: Exceptions, Previous: Rounding, Up: MPFR Basics [Index]
4.5 Floating-Point Values on Special Numbers
This section specifies the floating-point values (of type mpfr_t
)
returned by MPFR functions (where by “returned” we mean here the modified
value of the destination object, which should not be mixed with the ternary
return value of type int
of those 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 Rounding (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 possible. If the limit is not defined (e.g.,
mpfr_sqrt
and mpfr_log
on -0), the behavior is
specified in the description of the MPFR function, but must be consistent
with the rule from the above paragraph (e.g., mpfr_log
on ±0
gives -Inf).
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);
for example, mpfr_sin
on -0 gives -0 and
mpfr_acos
on 1 gives +0 (in all rounding modes).
In the other cases, the sign is specified in the description of the MPFR
function; for example mpfr_max
on -0 and +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 Transcendental Functions),
since for any finite or infinite input x, mpfr_hypot
on
(x,+Inf) gives +Inf.
Next: Memory Handling, Previous: Floating-Point Values on Special Numbers, Up: MPFR Basics [Index]
4.6 Exceptions
MPFR defines a global (or per-thread) flag for each supported exception. A macro evaluating to a power of two is associated with each flag and exception, in order to be able to specify a group of flags (or a mask) by OR’ing such macros.
Flags can be cleared (lowered), set (raised), and tested by functions described in Exception Related Functions.
The supported exceptions are listed below. The macro associated with each exception is in parentheses.
- Underflow (
MPFR_FLAGS_UNDERFLOW
): An underflow occurs when the exact result of a function is a non-zero real number and the result obtained after the rounding, assuming an unbounded exponent range (for the rounding), has an exponent smaller than the minimum value of the current exponent range. (In the round-to-nearest mode, the halfway case is rounded toward zero.)Note: This is not the single possible definition of the underflow. MPFR chooses to consider the underflow after rounding. The underflow before rounding can also be defined. For instance, consider a function that has the exact result 7 multiplied by two to the power e-4, where e is the smallest exponent (for a significand between 1/2 and 1), with a 2-bit target precision and rounding toward plus infinity. The exact result has the exponent e-1. With the underflow before rounding, such a function call would yield an underflow, as e-1 is outside the current exponent range. However, MPFR first considers the rounded result assuming an unbounded exponent range. The exact result cannot be represented exactly in precision 2, and here, it is rounded to 0.5 times 2 to e, which is representable in the current exponent range. As a consequence, this will not yield an underflow in MPFR.
- Overflow (
MPFR_FLAGS_OVERFLOW
): An overflow occurs when the exact result of a function is a non-zero real number and the result obtained after the rounding, assuming an unbounded exponent range (for the rounding), has an exponent larger than the maximum value of the current exponent range. In the round-to-nearest mode, the result is infinite. Note: unlike the underflow case, there is only one possible definition of overflow here. - Divide-by-zero (
MPFR_FLAGS_DIVBY0
): An exact infinite result is obtained from finite inputs. - NaN (
MPFR_FLAGS_NAN
): A NaN exception occurs when the result of a function is NaN. - Inexact (
MPFR_FLAGS_INEXACT
): An inexact exception occurs when the result of a function cannot be represented exactly and must be rounded. - Range error (
MPFR_FLAGS_ERANGE
): A range exception occurs when a function that does not return a MPFR number (such as comparisons and conversions to an integer) has an invalid result (e.g., an argument is NaN inmpfr_cmp
, or a conversion to an integer cannot be represented in the target type).
Moreover, the group consisting of all the flags is represented by
the MPFR_FLAGS_ALL
macro (if new flags are added in future
MPFR versions, they will be added to this macro too).
Differences with the ISO C99 standard:
- In C, only quiet NaNs are specified, and a NaN propagation does not raise an invalid exception. Unless explicitly stated otherwise, MPFR sets the NaN flag whenever a NaN is generated, even when a NaN is propagated (e.g., in NaN + NaN), as if all NaNs were signaling.
- An invalid exception in C corresponds to either a NaN exception or a range error in MPFR.
Next: Getting the Best Efficiency Out of MPFR, Previous: Exceptions, Up: MPFR Basics [Index]
4.7 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.
When more precision is needed, the value is automatically recomputed;
a minimum of 10% increase of the precision is guaranteed to avoid too
many recomputations.
MPFR functions may also create thread-local pools for internal use
to avoid the cost of memory allocation. The pools can be freed with
mpfr_free_pool
(but with a default MPFR build, they should not
take much memory, as the allocation size is limited).
At any time, the user can free various caches and pools with
mpfr_free_cache
and mpfr_free_cache2
. It is strongly advised
to free thread-local caches before terminating a thread, and all caches
before exiting when using tools like ‘valgrind’ (to avoid memory leaks
being reported).
MPFR allocates its memory either on the stack (for temporary memory only)
or with the same allocator as the one configured for GMP:
see Section “Custom Allocation” in GNU MP.
This means that the application must make sure that data allocated with the
current allocator will not be reallocated or freed with a new allocator.
So, in practice, if an application needs to change the allocator with
mp_set_memory_functions
, it should first free all data allocated
with the current allocator: for its own data, with mpfr_clear
,
etc.; for the caches and pools, with mpfr_mp_memory_cleanup
in
all threads where MPFR is potentially used. This function is currently
equivalent to mpfr_free_cache
, but mpfr_mp_memory_cleanup
is the recommended way in case the allocation method changes in the future
(for instance, one may choose to allocate the caches for floating-point
constants with malloc
to avoid freeing them if the allocator
changes). Developers should also be aware that MPFR may also be used
indirectly by libraries, so that libraries based on MPFR should provide
a clean-up function calling mpfr_mp_memory_cleanup
and/or warn
their users about this issue.
Note: For multithreaded applications, the allocator must be valid in all threads where MPFR may be used; data allocated in one thread may be reallocated and/or freed in some other thread.
MPFR internal data such as flags, the exponent range, the default precision, and the default rounding mode are either global (if MPFR has not been compiled as thread safe) or per-thread (thread-local storage, TLS). The initial values of TLS data after a thread is created entirely depend on the compiler and thread implementation (MPFR simply does a conventional variable initialization, the variables being declared with an implementation-defined TLS specifier).
Writers of libraries using MPFR should be aware that the application and/or another library used by the application may also use MPFR, so that changing the exponent range, the default precision, or the default rounding mode may have an effect on this other use of MPFR since these data are not duplicated (unless they are in a different thread). Therefore any such value changed in a library function should be restored before the function returns (unless the purpose of the function is to do such a change). Writers of software using MPFR should also be careful when changing such a value if they use a library using MPFR (directly or indirectly), in order to make sure that such a change is compatible with the library.
Previous: Memory Handling, Up: MPFR Basics [Index]
4.8 Getting the Best Efficiency Out of MPFR
Here are a few hints to get the best efficiency out of MPFR:
- you should avoid allocating and clearing variables. Reuse variables whenever possible, allocate or clear outside of loops, pass temporary variables to subroutines instead of allocating them inside the subroutines;
- use
mpfr_swap
instead ofmpfr_set
whenever possible. This will avoid copying the significands; - avoid using MPFR from C++, or make sure your C++ interface does not perform unnecessary allocations or copies;
- MPFR functions work in-place: to compute
a = a + b
you don’t need an auxiliary variable, you can directly writempfr_add (a, a, b, ...)
.
Previous: Memory Handling, Up: MPFR Basics [Index]