### 5.13 Exception Related Functions ¶

Function: `mpfr_exp_t` mpfr_get_emin `(void)` ¶
Function: `mpfr_exp_t` mpfr_get_emax `(void)` ¶

  Return the (current) smallest and largest exponents allowed for a floating-point variable. The smallest positive value of a floating-point variable is one half times 2 raised to the smallest exponent and the largest value has the form (1 − epsilon) times 2 raised to the largest exponent, where epsilon depends on the precision of the considered variable.

Function: `int` mpfr_set_emin `(mpfr_exp_t exp)` ¶
Function: `int` mpfr_set_emax `(mpfr_exp_t exp)` ¶

  Set the smallest and largest exponents allowed for a floating-point variable. Return a non-zero value when exp is not in the range accepted by the implementation (in that case the smallest or largest exponent is not changed), and zero otherwise.

  For the subsequent operations, it is the user’s responsibility to check that any floating-point value used as an input is in the new exponent range (for example using `mpfr_check_range`). If a floating-point value outside the new exponent range is used as an input, the default behavior is undefined, in the sense of the ISO C standard; the behavior may also be explicitly documented, such as for `mpfr_check_range`.

  Note: Caches may still have values outside the current exponent range. This is not an issue as the user cannot use these caches directly via the API (MPFR extends the exponent range internally when need be).

  If emin > emax and a floating-point value needs to be produced as output, the behavior is undefined (`mpfr_set_emin` and `mpfr_set_emax` do not check this condition as it might occur between successive calls to these two functions).

Function: `mpfr_exp_t` mpfr_get_emin_min `(void)` ¶
Function: `mpfr_exp_t` mpfr_get_emin_max `(void)` ¶
Function: `mpfr_exp_t` mpfr_get_emax_min `(void)` ¶
Function: `mpfr_exp_t` mpfr_get_emax_max `(void)` ¶

  Return the minimum and maximum of the exponents allowed for `mpfr_set_emin` and `mpfr_set_emax` respectively. These values are implementation dependent, thus a program using `mpfr_set_emax(mpfr_get_emax_max())` or `mpfr_set_emin(mpfr_get_emin_min())` may not be portable.

Function: `int` mpfr_check_range `(mpfr_t x, int t, mpfr_rnd_t rnd)` ¶

  This function assumes that x is the correctly rounded value of some real value y in the direction rnd and some extended exponent range, and that t is the corresponding ternary value. For example, one performed `t = mpfr_log (x, u, rnd)`, and y is the exact logarithm of u. Thus t is negative if x is smaller than y, positive if x is larger than y, and zero if x equals y. This function modifies x if needed to be in the current range of acceptable values: It generates an underflow or an overflow if the exponent of x is outside the current allowed range; the value of t may be used to avoid a double rounding. This function returns zero if the new value of x equals the exact one y, a positive value if that new value is larger than y, and a negative value if it is smaller than y. Note that unlike most functions, the new result x is compared to the (unknown) exact one y, not the input value x, i.e., the ternary value is propagated.

  Note: If x is an infinity and t is different from zero (i.e., if the rounded result is an inexact infinity), then the overflow flag is set. This is useful because `mpfr_check_range` is typically called (at least in MPFR functions) after restoring the flags that could have been set due to internal computations.

Function: `int` mpfr_subnormalize `(mpfr_t x, int t, mpfr_rnd_t rnd)` ¶

  This function rounds x emulating subnormal number arithmetic: if x is outside the subnormal exponent range of the emulated floating-point system, this function just propagates the ternary value t; otherwise, if EXP(x) denotes the exponent of x, it rounds x to precision EXP(x)−emin+1 according to rounding mode rnd and previous ternary value t, avoiding double rounding problems. More precisely in the subnormal domain, denoting by e the value of emin, x is rounded in fixed-point arithmetic to an integer multiple of two to the power e − 1; as a consequence, 1.5 multiplied by two to the power e − 1 when t is zero is rounded to two to the power e with rounding to nearest.

  The precision PREC(x) of x is not modified by this function. rnd and t must be the rounding mode and the returned ternary value used when computing x (as in `mpfr_check_range`). The subnormal exponent range is from emin to emin+PREC(x)−2. If the result cannot be represented in the current exponent range of MPFR (due to a too small emax), the behavior is undefined. Note that unlike most functions, the result is compared to the exact one, not the input value x, i.e., the ternary value is propagated.

  As usual, if the returned ternary value is non zero, the inexact flag is set. Moreover, if a second rounding occurred (because the input x was in the subnormal range), the underflow flag is set.

  Warning! If you change emin (with `mpfr_set_emin`) just before calling `mpfr_subnormalize`, you need to make sure that the value is in the current exponent range of MPFR. But it is better to change emin before any computation, if possible.

This is an example of how to emulate binary64 IEEE 754 arithmetic (a.k.a. double precision) using MPFR:

    {
      mpfr_t xa, xb; int i; volatile double a, b;

      mpfr_set_default_prec (53);
      mpfr_set_emin (-1073); mpfr_set_emax (1024);

      mpfr_init (xa); mpfr_init (xb);

      b = 34.3; mpfr_set_d (xb, b, MPFR_RNDN);
      a = 0x1.1235P-1021; mpfr_set_d (xa, a, MPFR_RNDN);

      a /= b;
      i = mpfr_div (xa, xa, xb, MPFR_RNDN);
      i = mpfr_subnormalize (xa, i, MPFR_RNDN); /* new ternary value */

      mpfr_clear (xa); mpfr_clear (xb);
    }

Note that `mpfr_set_emin` and `mpfr_set_emax` are called early enough in order to make sure that all computed values are in the current exponent range. Warning! This emulates a double IEEE 754 arithmetic with correct rounding in the subnormal range, which may not be the case for your hardware.

Below is another example showing how to emulate fixed-point arithmetic in a specific case. Here we compute the sine of the integers 1 to 17 with a result in a fixed-point arithmetic rounded at two to the power −42 (using the fact that the result is at most 1 in absolute value):

    {
      mpfr_t x; int i, inex;

      mpfr_set_emin (-41);
      mpfr_init2 (x, 42);
      for (i = 1; i <= 17; i++)
        {
          mpfr_set_ui (x, i, MPFR_RNDN);
          inex = mpfr_sin (x, x, MPFR_RNDZ);
          mpfr_subnormalize (x, inex, MPFR_RNDZ);
          mpfr_dump (x);
        }
      mpfr_clear (x);
    }

Function: `void` mpfr_clear_underflow `(void)` ¶
Function: `void` mpfr_clear_overflow `(void)` ¶
Function: `void` mpfr_clear_divby0 `(void)` ¶
Function: `void` mpfr_clear_nanflag `(void)` ¶
Function: `void` mpfr_clear_inexflag `(void)` ¶
Function: `void` mpfr_clear_erangeflag `(void)` ¶

  Clear (lower) the underflow, overflow, divide-by-zero, invalid, inexact and erange flags.

Function: `void` mpfr_clear_flags `(void)` ¶

  Clear (lower) all global flags (underflow, overflow, divide-by-zero, invalid, inexact, erange). Note: a group of flags can be cleared by using `mpfr_flags_clear`.

Function: `void` mpfr_set_underflow `(void)` ¶
Function: `void` mpfr_set_overflow `(void)` ¶
Function: `void` mpfr_set_divby0 `(void)` ¶
Function: `void` mpfr_set_nanflag `(void)` ¶
Function: `void` mpfr_set_inexflag `(void)` ¶
Function: `void` mpfr_set_erangeflag `(void)` ¶

  Set (raise) the underflow, overflow, divide-by-zero, invalid, inexact and erange flags.

Function: `int` mpfr_underflow_p `(void)` ¶
Function: `int` mpfr_overflow_p `(void)` ¶
Function: `int` mpfr_divby0_p `(void)` ¶
Function: `int` mpfr_nanflag_p `(void)` ¶
Function: `int` mpfr_inexflag_p `(void)` ¶
Function: `int` mpfr_erangeflag_p `(void)` ¶

  Return the corresponding (underflow, overflow, divide-by-zero, invalid, inexact, erange) flag, which is non-zero iff the flag is set.

The `mpfr_flags_` functions below that take an argument mask can operate on any subset of the exception flags: a flag is part of this subset (or group) if and only if the corresponding bit of the argument mask is set. The `MPFR_FLAGS_` macros will normally be used to build this argument. See Exceptions.

Function: `void` mpfr_flags_clear `(mpfr_flags_t mask)` ¶

  Clear (lower) the group of flags specified by mask.

Function: `void` mpfr_flags_set `(mpfr_flags_t mask)` ¶

  Set (raise) the group of flags specified by mask.

Function: `mpfr_flags_t` mpfr_flags_test `(mpfr_flags_t mask)` ¶

  Return the flags specified by mask. To test whether any flag from mask is set, compare the return value to 0. You can also test individual flags by AND’ing the result with `MPFR_FLAGS_` macros. Example:

      mpfr_flags_t t = mpfr_flags_test (MPFR_FLAGS_UNDERFLOW|
                                        MPFR_FLAGS_OVERFLOW)
      ...
      if (t)  /* underflow and/or overflow (unlikely) */
        {
          if (t & MPFR_FLAGS_UNDERFLOW)  { /* handle underflow */ }
          if (t & MPFR_FLAGS_OVERFLOW)   { /* handle overflow  */ }
        }

Function: `mpfr_flags_t` mpfr_flags_save `(void)` ¶

  Return all the flags. It is equivalent to `mpfr_flags_test(MPFR_FLAGS_ALL)`.

Function: `void` mpfr_flags_restore `(mpfr_flags_t flags, mpfr_flags_t mask)` ¶

  Restore the flags specified by mask to their state represented in flags.