pub const API_Compatibility: ();
Expand description

This constant is a place-holder for documentation; do not use it in code.


6 API Compatibility

The goal of this section is to describe some API changes that occurred from one version of MPFR to another, and how to write code that can be compiled and run with older MPFR versions. The minimum MPFR version that is considered here is 2.2.0 (released on 20 September 2005).

API changes can only occur between major or minor versions. Thus the patchlevel (the third number in the MPFR version) will be ignored in the following. If a program does not use MPFR internals, changes in the behavior between two versions differing only by the patchlevel should only result from what was regarded as a bug or unspecified behavior.

As a general rule, a program written for some MPFR version should work with later versions, possibly except at a new major version, where some features (described as obsolete for some time) can be removed. In such a case, a failure should occur during compilation or linking. If a result becomes incorrect because of such a change, please look at the various changes below (they are minimal, and most software should be unaffected), at the FAQ and at the MPFR web page for your version (a bug could have been introduced and be already fixed); and if the problem is not mentioned, please send us a bug report (see Reporting Bugs).

However, a program written for the current MPFR version (as documented by this manual) may not necessarily work with previous versions of MPFR. This section should help developers to write portable code.

Note: Information given here may be incomplete. API changes are also described in the NEWS file (for each version, instead of being classified like here), together with other changes.


6.1 Type and Macro Changes

The official type for exponent values changed from mp_exp_t to mpfr_exp_t in MPFR 3.0. The type mp_exp_t will remain available as it comes from GMP (with a different meaning). These types are currently the same (mpfr_exp_t is defined as mp_exp_t with typedef), so that programs can still use mp_exp_t; but this may change in the future. Alternatively, using the following code after including mpfr.h will work with official MPFR versions, as mpfr_exp_t was never defined in MPFR 2.x:

#if MPFR_VERSION_MAJOR < 3
typedef mp_exp_t mpfr_exp_t;
#endif

The official types for precision values and for rounding modes respectively changed from mp_prec_t and mp_rnd_t to mpfr_prec_t and mpfr_rnd_t in MPFR 3.0. This change was actually done a long time ago in MPFR, at least since MPFR 2.2.0, with the following code in mpfr.h:

#ifndef mp_rnd_t
# define mp_rnd_t  mpfr_rnd_t
#endif
#ifndef mp_prec_t
# define mp_prec_t mpfr_prec_t
#endif

This means that it is safe to use the new official types mpfr_prec_t and mpfr_rnd_t in your programs. The types mp_prec_t and mp_rnd_t (defined in MPFR only) may be removed in the future, as the prefix mp_ is reserved by GMP.

The precision type mpfr_prec_t (mp_prec_t) was unsigned before MPFR 3.0; it is now signed. MPFR_PREC_MAX has not changed, though. Indeed the MPFR code requires that MPFR_PREC_MAX be representable in the exponent type, which may have the same size as mpfr_prec_t but has always been signed. The consequence is that valid code that does not assume anything about the signedness of mpfr_prec_t should work with past and new MPFR versions. This change was useful as the use of unsigned types tends to convert signed values to unsigned ones in expressions due to the usual arithmetic conversions, which can yield incorrect results if a negative value is converted in such a way. Warning! A program assuming (intentionally or not) that mpfr_prec_t is signed may be affected by this problem when it is built and run against MPFR 2.x.

The rounding modes GMP_RNDx were renamed to MPFR_RNDx in MPFR 3.0. However, the old names GMP_RNDx have been kept for compatibility (this might change in future versions), using:

#define GMP_RNDN MPFR_RNDN
#define GMP_RNDZ MPFR_RNDZ
#define GMP_RNDU MPFR_RNDU
#define GMP_RNDD MPFR_RNDD

The rounding mode “round away from zero” (MPFR_RNDA) was added in MPFR 3.0 (however, no rounding mode GMP_RNDA exists). Faithful rounding (MPFR_RNDF) was added in MPFR 4.0, but currently, it is partially supported.

The flags-related macros, whose name starts with MPFR_FLAGS_, were added in MPFR 4.0 (for the new functions mpfr_flags_clear, mpfr_flags_restore, mpfr_flags_set and mpfr_flags_test, in particular).


6.2 Added Functions

We give here in alphabetical order the functions (and function-like macros) that were added after MPFR 2.2, and in which MPFR version.

  • mpfr_acospi and mpfr_acosu in MPFR 4.2.
  • mpfr_add_d in MPFR 2.4.
  • mpfr_ai in MPFR 3.0 (incomplete, experimental).
  • mpfr_asinpi and mpfr_asinu in MPFR 4.2.
  • mpfr_asprintf in MPFR 2.4.
  • mpfr_atan2pi and mpfr_atan2u in MPFR 4.2.
  • mpfr_atanpi and mpfr_atanu in MPFR 4.2.
  • mpfr_beta in MPFR 4.0 (incomplete, experimental).
  • mpfr_buildopt_decimal_p in MPFR 3.0.
  • mpfr_buildopt_float128_p in MPFR 4.0.
  • mpfr_buildopt_gmpinternals_p in MPFR 3.1.
  • mpfr_buildopt_sharedcache_p in MPFR 4.0.
  • mpfr_buildopt_tls_p in MPFR 3.0.
  • mpfr_buildopt_tune_case in MPFR 3.1.
  • mpfr_clear_divby0 in MPFR 3.1 (new divide-by-zero exception).
  • mpfr_cmpabs_ui in MPFR 4.1.
  • mpfr_compound_si in MPFR 4.2.
  • mpfr_copysign in MPFR 2.3. Note: MPFR 2.2 had a mpfr_copysign function that was available, but not documented, and with a slight difference in the semantics (when the second input operand is a NaN).
  • mpfr_cospi and mpfr_cosu in MPFR 4.2.
  • mpfr_custom_get_significand in MPFR 3.0. This function was named mpfr_custom_get_mantissa in previous versions; mpfr_custom_get_mantissa is still available via a macro in mpfr.h:
    #define mpfr_custom_get_mantissa mpfr_custom_get_significand
    

    Thus code that needs to work with both MPFR 2.x and MPFR 3.x should use mpfr_custom_get_mantissa.

  • mpfr_d_div and mpfr_d_sub in MPFR 2.4.
  • mpfr_digamma in MPFR 3.0.
  • mpfr_divby0_p in MPFR 3.1 (new divide-by-zero exception).
  • mpfr_div_d in MPFR 2.4.
  • mpfr_dot in MPFR 4.1 (incomplete, experimental).
  • mpfr_erandom in MPFR 4.0.
  • mpfr_exp2m1 and mpfr_exp10m1 in MPFR 4.2.
  • mpfr_flags_clear, mpfr_flags_restore, mpfr_flags_save, mpfr_flags_set and mpfr_flags_test in MPFR 4.0.
  • mpfr_fmma and mpfr_fmms in MPFR 4.0.
  • mpfr_fmod in MPFR 2.4.
  • mpfr_fmodquo in MPFR 4.0.
  • mpfr_fmod_ui in MPFR 4.2.
  • mpfr_fms in MPFR 2.3.
  • mpfr_fpif_export and mpfr_fpif_import in MPFR 4.0.
  • mpfr_fprintf in MPFR 2.4.
  • mpfr_free_cache2 in MPFR 4.0.
  • mpfr_free_pool in MPFR 4.0.
  • mpfr_frexp in MPFR 3.1.
  • mpfr_gamma_inc in MPFR 4.0.
  • mpfr_get_decimal128 in MPFR 4.1.
  • mpfr_get_float128 in MPFR 4.0 if configured with ‘--enable-float128’.
  • mpfr_get_flt in MPFR 3.0.
  • mpfr_get_patches in MPFR 2.3.
  • mpfr_get_q in MPFR 4.0.
  • mpfr_get_str_ndigits in MPFR 4.1.
  • mpfr_get_z_2exp in MPFR 3.0. This function was named mpfr_get_z_exp in previous versions; mpfr_get_z_exp is still available via a macro in mpfr.h:
    #define mpfr_get_z_exp mpfr_get_z_2exp
    

    Thus code that needs to work with both MPFR 2.x and MPFR 3.x should use mpfr_get_z_exp.

  • mpfr_grandom in MPFR 3.1.
  • mpfr_j0, mpfr_j1 and mpfr_jn in MPFR 2.3.
  • mpfr_log2p1 and mpfr_log10p1 in MPFR 4.2.
  • mpfr_lgamma in MPFR 2.3.
  • mpfr_li2 in MPFR 2.4.
  • mpfr_log_ui in MPFR 4.0.
  • mpfr_min_prec in MPFR 3.0.
  • mpfr_modf in MPFR 2.4.
  • mpfr_mp_memory_cleanup in MPFR 4.0.
  • mpfr_mul_d in MPFR 2.4.
  • mpfr_nrandom in MPFR 4.0.
  • mpfr_powr, mpfr_pown, mpfr_pow_sj and mpfr_pow_uj in MPFR 4.2.
  • mpfr_printf in MPFR 2.4.
  • mpfr_rec_sqrt in MPFR 2.4.
  • mpfr_regular_p in MPFR 3.0.
  • mpfr_remainder and mpfr_remquo in MPFR 2.3.
  • mpfr_rint_roundeven and mpfr_roundeven in MPFR 4.0.
  • mpfr_round_nearest_away in MPFR 4.0.
  • mpfr_rootn_si in MPFR 4.2.
  • mpfr_rootn_ui in MPFR 4.0.
  • mpfr_set_decimal128 in MPFR 4.1.
  • mpfr_set_divby0 in MPFR 3.1 (new divide-by-zero exception).
  • mpfr_set_float128 in MPFR 4.0 if configured with ‘--enable-float128’.
  • mpfr_set_flt in MPFR 3.0.
  • mpfr_set_z_2exp in MPFR 3.0.
  • mpfr_set_zero in MPFR 3.0.
  • mpfr_setsign in MPFR 2.3.
  • mpfr_signbit in MPFR 2.3.
  • mpfr_sinh_cosh in MPFR 2.4.
  • mpfr_sinpi and mpfr_sinu in MPFR 4.2.
  • mpfr_snprintf and mpfr_sprintf in MPFR 2.4.
  • mpfr_sub_d in MPFR 2.4.
  • mpfr_tanpi and mpfr_tanu in MPFR 4.2.
  • mpfr_total_order_p in MPFR 4.1.
  • mpfr_urandom in MPFR 3.0.
  • mpfr_vasprintf, mpfr_vfprintf, mpfr_vprintf, mpfr_vsprintf and mpfr_vsnprintf in MPFR 2.4.
  • mpfr_y0, mpfr_y1 and mpfr_yn in MPFR 2.3.
  • mpfr_z_sub in MPFR 3.1.

6.3 Changed Functions

The following functions and function-like macros have changed after MPFR 2.2. Changes can affect the behavior of code written for some MPFR version when built and run against another MPFR version (older or newer), as described below.

  • The formatted output functions (mpfr_printf, etc.) have slightly changed in MPFR 4.1 in the case where the precision field is empty: trailing zeros were not output with the conversion specifier ‘e’ / ‘E’ (the chosen precision was not fully specified and it depended on the input value), and also on the value zero with the conversion specifiers ‘f’ / ‘F’ / ‘g’ / ‘G’ (this could partly be regarded as a bug); they are now kept in a way similar to the formatted output functions from C. Moreover, the case where the precision consists only of a period has been fixed in MPFR 4.2 to be like ‘.0’ as specified in the ISO C standard (it previously behaved as a missing precision).
  • mpfr_abs, mpfr_neg and mpfr_set changed in MPFR 4.0. In previous MPFR versions, the sign bit of a NaN was unspecified; however, in practice, it was set as now specified except for mpfr_neg with a reused argument: mpfr_neg(x,x,rnd).
  • mpfr_check_range changed in MPFR 2.3.2 and MPFR 2.4. If the value is an inexact infinity, the overflow flag is now set (in case it was lost), while it was previously left unchanged. This is really what is expected in practice (and what the MPFR code was expecting), so that the previous behavior was regarded as a bug. Hence the change in MPFR 2.3.2.
  • mpfr_eint changed in MPFR 4.0. This function now returns the value of the E1/eint1 function for negative argument (before MPFR 4.0, it was returning NaN).
  • mpfr_get_f changed in MPFR 3.0. This function was returning zero, except for NaN and Inf, which do not exist in MPF. The erange flag is now set in these cases, and mpfr_get_f now returns the usual ternary value.
  • mpfr_get_si, mpfr_get_sj, mpfr_get_ui and mpfr_get_uj changed in MPFR 3.0. In previous MPFR versions, the cases where the erange flag is set were unspecified.
  • mpfr_get_str changed in MPFR 4.0. This function now sets the NaN flag on NaN input (to follow the usual MPFR rules on NaN and IEEE 754 recommendations on string conversions from Subclause 5.12.1) and sets the inexact flag when the conversion is inexact.
  • mpfr_get_z changed in MPFR 3.0. The return type was void; it is now int, and the usual ternary value is returned. Thus programs that need to work with both MPFR 2.x and 3.x must not use the return value. Even in this case, C code using mpfr_get_z as the second or third term of a conditional operator may also be affected. For instance, the following is correct with MPFR 3.0, but not with MPFR 2.x:
    bool ? mpfr_get_z(...) : mpfr_add(...);
    

    On the other hand, the following is correct with MPFR 2.x, but not with MPFR 3.0:

    bool ? mpfr_get_z(...) : (void) mpfr_add(...);
    

    Portable code should cast mpfr_get_z(...) to void to use the type void for both terms of the conditional operator, as in:

    bool ? (void) mpfr_get_z(...) : (void) mpfr_add(...);
    

    Alternatively, if ... else can be used instead of the conditional operator.

    Moreover the cases where the erange flag is set were unspecified in MPFR 2.x.

  • mpfr_get_z_exp changed in MPFR 3.0. In previous MPFR versions, the cases where the erange flag is set were unspecified. Note: this function has been renamed to mpfr_get_z_2exp in MPFR 3.0, but mpfr_get_z_exp is still available for compatibility reasons.
  • mpfr_out_str changed in MPFR 4.1. The argument base can now be negative (from −2 to −36), in order to follow mpfr_get_str and GMP’s mpf_out_str functions.
  • mpfr_set_exp changed in MPFR 4.0. Before MPFR 4.0, the exponent was set whatever the contents of the MPFR object in argument. In practice, this could be useful as a low-level function when the MPFR number was being constructed by setting the fields of its internal structure, but the API does not provide a way to do this except by using internals. Thus, for the API, this behavior was useless and could quickly lead to undefined behavior due to the fact that the generated value could have an invalid format if the MPFR object contained a special value (NaN, infinity or zero).
  • mpfr_strtofr changed in MPFR 2.3.1 and MPFR 2.4. This was actually a bug fix since the code and the documentation did not match. But both were changed in order to have a more consistent and useful behavior. The main changes in the code are as follows. The binary exponent is now accepted even without the ‘0b’ or ‘0x’ prefix. Data corresponding to NaN can now have an optional sign (such data were previously invalid).
  • mpfr_strtofr changed in MPFR 3.0. This function now accepts bases from 37 to 62 (no changes for the other bases). Note: if an unsupported base is provided to this function, the behavior is undefined; more precisely, in MPFR 2.3.1 and later, providing an unsupported base yields an assertion failure (this behavior may change in the future).
  • mpfr_subnormalize changed in MPFR 3.1. This was actually regarded as a bug fix. The mpfr_subnormalize implementation up to MPFR 3.0.0 did not change the flags. In particular, it did not follow the generic rule concerning the inexact flag (and no special behavior was specified). The case of the underflow flag was more a lack of specification.
  • mpfr_sum changed in MPFR 4.0. The mpfr_sum function has completely been rewritten for MPFR 4.0, with an update of the specification: the sign of an exact zero result is now specified, and the return value is now the usual ternary value. The old mpfr_sum implementation could also take all the memory and crash on inputs of very different magnitude.
  • mpfr_urandom and mpfr_urandomb changed in MPFR 3.1. Their behavior no longer depends on the platform (assuming this is also true for GMP’s random generator, which is not the case between GMP 4.1 and 4.2 if gmp_randinit_default is used). As a consequence, the returned values can be different between MPFR 3.1 and previous MPFR versions. Note: as the reproducibility of these functions was not specified before MPFR 3.1, the MPFR 3.1 behavior is not regarded as backward incompatible with previous versions.
  • mpfr_urandom changed in MPFR 4.0. The next random state no longer depends on the current exponent range and the rounding mode. The exceptions due to the rounding of the random number are now correctly generated, following the uniform distribution. As a consequence, the returned values can be different between MPFR 4.0 and previous MPFR versions.
  • Up to MPFR 4.1.0, some macros of the Custom Interface had undocumented limitations. In particular, their arguments may be evaluated multiple times or none.

6.4 Removed Functions

Functions mpfr_random and mpfr_random2 have been removed in MPFR 3.0 (this only affects old code built against MPFR 3.0 or later). (The function mpfr_random had been deprecated since at least MPFR 2.2.0, and mpfr_random2 since MPFR 2.4.0.)

Macros mpfr_add_one_ulp and mpfr_sub_one_ulp have been removed in MPFR 4.0. They were no longer documented since MPFR 2.1.0 and were announced as deprecated since MPFR 3.1.0.

Function mpfr_grandom is marked as deprecated in MPFR 4.0. It will be removed in a future release.


6.5 Other Changes

For users of a C++ compiler, the way how the availability of intmax_t is detected has changed in MPFR 3.0. In MPFR 2.x, if a macro INTMAX_C or UINTMAX_C was defined (e.g. when the __STDC_CONSTANT_MACROS macro had been defined before <stdint.h> or <inttypes.h> has been included), intmax_t was assumed to be defined. However, this was not always the case (more precisely, intmax_t can be defined only in the namespace std, as with Boost), so that compilations could fail. Thus the check for INTMAX_C or UINTMAX_C is now disabled for C++ compilers, with the following consequences:

  • Programs written for MPFR 2.x that need intmax_t may no longer be compiled against MPFR 3.0: a #define MPFR_USE_INTMAX_T may be necessary before mpfr.h is included.
  • The compilation of programs that work with MPFR 3.0 may fail with MPFR 2.x due to the problem described above. Workarounds are possible, such as defining intmax_t and uintmax_t in the global namespace, though this is not clean.

The divide-by-zero exception is new in MPFR 3.1. However, it should not introduce incompatible changes for programs that strictly follow the MPFR API since the exception can only be seen via new functions.

As of MPFR 3.1, the mpfr.h header can be included several times, while still supporting optional functions (see Headers and Libraries).

The way memory is allocated by MPFR should be regarded as well-specified only as of MPFR 4.0.