1105401Stmm/* mpfr_get_z -- get a multiple-precision integer from 2105401Stmm a floating-point number 3105401Stmm 4105401StmmCopyright 2004, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc. 5105401StmmContributed by the AriC and Caramel projects, INRIA. 6105401Stmm 7105401StmmThis file is part of the GNU MPFR Library. 8105401Stmm 9105401StmmThe GNU MPFR Library is free software; you can redistribute it and/or modify 10105401Stmmit under the terms of the GNU Lesser General Public License as published by 11105401Stmmthe Free Software Foundation; either version 3 of the License, or (at your 12105401Stmmoption) any later version. 13105401Stmm 14105401StmmThe GNU MPFR Library is distributed in the hope that it will be useful, but 15105401StmmWITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 16105401Stmmor FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 17105401StmmLicense for more details. 18105401Stmm 19105401StmmYou should have received a copy of the GNU Lesser General Public License 20105401Stmmalong with the GNU MPFR Library; see the file COPYING.LESSER. If not, see 21105401Stmmhttp://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., 22105401Stmm51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ 23105401Stmm 24105401Stmm#include "mpfr-impl.h" 25105401Stmm 26105401Stmmint 27105401Stmmmpfr_get_z (mpz_ptr z, mpfr_srcptr f, mpfr_rnd_t rnd) 28105401Stmm{ 29129589Smarius int inex; 30129589Smarius mpfr_t r; 31129589Smarius mpfr_exp_t exp; 32129589Smarius 33129589Smarius if (MPFR_UNLIKELY (MPFR_IS_SINGULAR (f))) 34105401Stmm { 35105401Stmm if (MPFR_UNLIKELY (MPFR_NOTZERO (f))) 36129589Smarius MPFR_SET_ERANGE (); 37129589Smarius mpz_set_ui (z, 0); 38105401Stmm /* The ternary value is 0 even for infinity. Giving the rounding 39129589Smarius direction in this case would not make much sense anyway, and 40105401Stmm the direction would not necessarily match rnd. */ 41105401Stmm return 0; 42105401Stmm } 43129589Smarius 44129589Smarius exp = MPFR_GET_EXP (f); 45129589Smarius /* if exp <= 0, then |f|<1, thus |o(f)|<=1 */ 46129589Smarius MPFR_ASSERTN (exp < 0 || exp <= MPFR_PREC_MAX); 47129589Smarius mpfr_init2 (r, (exp < (mpfr_exp_t) MPFR_PREC_MIN ? 48129589Smarius MPFR_PREC_MIN : (mpfr_prec_t) exp)); 49105401Stmm inex = mpfr_rint (r, f, rnd); 50129589Smarius MPFR_ASSERTN (inex != 1 && inex != -1); /* integral part of f is 51129589Smarius representable in r */ 52129589Smarius MPFR_ASSERTN (MPFR_IS_FP (r)); 53129589Smarius exp = mpfr_get_z_2exp (z, r); 54129589Smarius if (exp >= 0) 55129589Smarius mpz_mul_2exp (z, z, exp); 56129589Smarius else 57105401Stmm mpz_fdiv_q_2exp (z, z, -exp); 58105401Stmm mpfr_clear (r); 59105401Stmm 60105401Stmm return inex; 61105401Stmm} 62105401Stmm