1/* mpfr_fits_*_p -- test whether an mpfr fits a C signed type. 2 3Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc. 4Contributed by the AriC and Caramel projects, INRIA. 5 6This file is part of the GNU MPFR Library. 7 8The GNU MPFR Library is free software; you can redistribute it and/or modify 9it under the terms of the GNU Lesser General Public License as published by 10the Free Software Foundation; either version 3 of the License, or (at your 11option) any later version. 12 13The GNU MPFR Library is distributed in the hope that it will be useful, but 14WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 15or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 16License for more details. 17 18You should have received a copy of the GNU Lesser General Public License 19along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see 20http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., 2151 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ 22 23#include "mpfr-impl.h" 24 25/* The original version of this file came from GMP's mpf/fits_s.h; 26 it has been adapted for MPFR. In particular, the result can be 27 rounded away from zero. */ 28 29int 30FUNCTION (mpfr_srcptr f, mpfr_rnd_t rnd) 31{ 32 mpfr_exp_t e; 33 int prec; 34 mpfr_t x; 35 int neg; 36 int res; 37 38 if (MPFR_UNLIKELY (MPFR_IS_SINGULAR (f))) 39 /* Zero always fit */ 40 return MPFR_IS_ZERO (f) ? 1 : 0; 41 42 /* now it fits if either 43 (a) MINIMUM <= f <= MAXIMUM 44 (b) or MINIMUM <= round(f, prec(slong), rnd) <= MAXIMUM */ 45 46 e = MPFR_GET_EXP (f); 47 if (e < 1) 48 return 1; /* |f| < 1: always fits */ 49 50 neg = MPFR_IS_NEG (f); 51 52 /* let EXTREMUM be MAXIMUM if f > 0, and MINIMUM if f < 0 */ 53 54 /* first compute prec(EXTREMUM), this could be done at configure time, 55 but the result can depend on neg (the loop is moved inside the "if" 56 to give the compiler a better chance to compute prec statically) */ 57 if (neg) 58 { 59 unsigned TYPE s; 60 /* In C89, the division on negative integers isn't well-defined. */ 61 s = SAFE_ABS (unsigned TYPE, MINIMUM); 62 for (prec = 0; s != 0; s /= 2, prec ++); 63 } 64 else 65 { 66 TYPE s; 67 s = MAXIMUM; 68 for (prec = 0; s != 0; s /= 2, prec ++); 69 } 70 71 /* EXTREMUM needs prec bits, i.e. 2^(prec-1) <= |EXTREMUM| < 2^prec */ 72 73 /* if e <= prec - 1, then f < 2^(prec-1) <= |EXTREMUM| */ 74 if (e <= prec - 1) 75 return 1; 76 77 /* if e >= prec + 1, then f >= 2^prec > |EXTREMUM| */ 78 if (e >= prec + 1) 79 return 0; 80 81 MPFR_ASSERTD (e == prec); 82 83 /* hard case: first round to prec bits, then check */ 84 mpfr_init2 (x, prec); 85 mpfr_set (x, f, rnd); 86 res = neg ? (mpfr_cmp_si (x, MINIMUM) >= 0) : (MPFR_GET_EXP (x) == e); 87 mpfr_clear (x); 88 return res; 89} 90