mpfr

Are there predicate functions to compare mpfr_t with double?


There are predicate functions to compare mpfr_t with mpfr_t. For example:

int mpfr_greaterequal_p (mpfr_t op1, mpfr_t op2)
int mpfr_lessequal_p (mpfr_t op1, mpfr_t op2)

Are there predicate functions to compare mpfr_t with double? For example:

int mpfr_greaterequal_p_d (mpfr_t op1, double op2)
int mpfr_lessequal_p_d (mpfr_t op1, double op2)

If no, then:

  1. Why?
  2. What's the most efficient way to perform, for example, mpfr_t >= 2.0 comparison?

Extra: per my experience, systems / ISAs / FP implementations may provide only three predicates: ==, <= (or >=), < (or >), because they are sufficient. As I see, MPFR provides at least five predicates: >, >=, <, <=, ==. A simple question: then why there is no != predicate (e.g. mpfr_unequal_p)?


Solution

  • There are currently no predicates to compare mpfr_t with double, mainly because they have not been added. Note that mixed operations with double are there to potentially make the use of MPFR a bit easier. But they are not more efficient, because the double argument is typically converted to a MPFR number first. For instance, see the current implementation of mpfr_cmp_d, which does a conversion and uses mpfr_cmp.

    Note that 3 predicates are not sufficient due to unordered (caused by NaN). The 4 mutually exclusive relations (less than, equal, greater than, and unordered) give 24 = 16 possibilities. So one needs 7 predicates (to avoid the need of combinations of 2 predicates): with a NOT, one gets 2 × 7 = 14 predicates, and the remaining 2 predicates true and false are useless. MPFR provides such 7 predicates: mpfr_greater_p, mpfr_greaterequal_p, mpfr_less_p, mpfr_lessequal_p, mpfr_equal_p, mpfr_lessgreater_p, mpfr_unordered_p.

    To quote comparisons.c:

    /*                          =     <     >     unordered
     * mpfr_greater_p           0     0     1     0
     * mpfr_greaterequal_p      1     0     1     0
     * mpfr_less_p              0     1     0     0
     * mpfr_lessequal_p         1     1     0     0
     * mpfr_lessgreater_p       0     1     1     0
     * mpfr_equal_p             1     0     0     0
     * mpfr_unordered_p         0     0     0     1
     */
    

    If you take the negation of mpfr_unordered_p, you get (1,1,1,0). So you have every combination of (x,y,z,0) except the useless (0,0,0,0). The combinations of (x,y,z,1), except the useless (1,1,1,1), are obtained by taking the NOT of the result.