/* * Check if x is a valid mpfr_t initializes by mpfr_init * Returns 0 if isn't valid */ int mpfr_check (mpfr_srcptr x) { mp_size_t s, i; mp_limb_t tmp; volatile mp_limb_t *xm; mpfr_prec_t prec; int rw; /* Check sign */ if (MPFR_SIGN(x) != MPFR_SIGN_POS && MPFR_SIGN(x) != MPFR_SIGN_NEG) return 0; /* Check precision */ prec = MPFR_PREC(x); if (prec < MPFR_PREC_MIN || prec > MPFR_PREC_MAX) return 0; /* Check mantissa */ xm = MPFR_MANT(x); if (xm == NULL) return 0; /* Check size of mantissa */ s = MPFR_GET_ALLOC_SIZE(x); if (s <= 0 || s > MP_SIZE_T_MAX || prec > (mpfr_prec_t) s * GMP_NUMB_BITS) return 0; /* Acces all the mp_limb of the mantissa: may do a seg fault */ for (i = 0 ; i < s ; i++) tmp = xm[i]; /* Check singular numbers (do not use MPFR_IS_PURE_FP() in order to avoid any assertion checking, as this function mpfr_check() does something similar by returning a Boolean instead of doing an abort if the format is incorrect). */ if (MPFR_IS_SINGULAR (x)) return MPFR_IS_ZERO(x) || MPFR_IS_NAN(x) || MPFR_IS_INF(x); /* Check the most significant limb (its MSB must be 1) */ if ((xm[MPFR_LAST_LIMB(x)] & MPFR_LIMB_HIGHBIT) == 0) return 0; /* Check the least significant limb (the trailing bits must be 0) */ rw = prec % GMP_NUMB_BITS; if (rw != 0) { tmp = MPFR_LIMB_MASK (GMP_NUMB_BITS - rw); if ((xm[0] & tmp) != 0) return 0; } /* Check exponent range */ if (MPFR_EXP (x) < __gmpfr_emin || MPFR_EXP (x) > __gmpfr_emax) return 0; return 1; }
MPFR_HOT_FUNCTION_ATTR int mpfr_cmp3 (mpfr_srcptr b, mpfr_srcptr c, int s) { mpfr_exp_t be, ce; mp_size_t bn, cn; mp_limb_t *bp, *cp; s = MPFR_MULT_SIGN( s , MPFR_SIGN(c) ); if (MPFR_ARE_SINGULAR(b, c)) { if (MPFR_IS_NAN (b) || MPFR_IS_NAN (c)) { MPFR_SET_ERANGEFLAG (); return 0; } else if (MPFR_IS_INF(b)) { if (MPFR_IS_INF(c) && s == MPFR_SIGN(b) ) return 0; else return MPFR_SIGN(b); } else if (MPFR_IS_INF(c)) return -s; else if (MPFR_IS_ZERO(b)) return MPFR_IS_ZERO(c) ? 0 : -s; else /* necessarily c=0 */ return MPFR_SIGN(b); } /* b and c are real numbers */ if (s != MPFR_SIGN(b)) return MPFR_SIGN(b); /* now signs are equal */ be = MPFR_GET_EXP (b); ce = MPFR_GET_EXP (c); if (be > ce) return s; if (be < ce) return -s; /* both signs and exponents are equal */ bn = MPFR_LAST_LIMB (b); cn = MPFR_LAST_LIMB (c); bp = MPFR_MANT(b); cp = MPFR_MANT(c); for ( ; bn >= 0 && cn >= 0; bn--, cn--) { if (bp[bn] > cp[cn]) return s; if (bp[bn] < cp[cn]) return -s; } for ( ; bn >= 0; bn--) if (bp[bn]) return s; for ( ; cn >= 0; cn--) if (cp[cn]) return -s; return 0; }