1/* mpfr_set_ui_2exp -- set a MPFR number from a machine unsigned integer with 2 a shift 3 4Copyright 2004, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc. 5Contributed by the AriC and Caramel projects, INRIA. 6 7This file is part of the GNU MPFR Library. 8 9The GNU MPFR Library is free software; you can redistribute it and/or modify 10it under the terms of the GNU Lesser General Public License as published by 11the Free Software Foundation; either version 3 of the License, or (at your 12option) any later version. 13 14The GNU MPFR Library is distributed in the hope that it will be useful, but 15WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 16or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 17License for more details. 18 19You should have received a copy of the GNU Lesser General Public License 20along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see 21http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., 2251 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ 23 24#define MPFR_NEED_LONGLONG_H 25#include "mpfr-impl.h" 26 27int 28mpfr_set_ui_2exp (mpfr_ptr x, unsigned long i, mpfr_exp_t e, mpfr_rnd_t rnd_mode) 29{ 30 MPFR_SET_POS (x); 31 32 if (i == 0) 33 { 34 MPFR_SET_ZERO (x); 35 MPFR_RET (0); 36 } 37 else 38 { 39 mp_size_t xn; 40 unsigned int cnt, nbits; 41 mp_limb_t *xp; 42 int inex = 0; 43 44 /* FIXME: support int limbs (e.g. 16-bit limbs on 16-bit proc) */ 45 MPFR_ASSERTD (i == (mp_limb_t) i); 46 47 /* Position of the highest limb */ 48 xn = (MPFR_PREC (x) - 1) / GMP_NUMB_BITS; 49 count_leading_zeros (cnt, (mp_limb_t) i); 50 MPFR_ASSERTD (cnt < GMP_NUMB_BITS); /* OK since i != 0 */ 51 52 xp = MPFR_MANT(x); 53 xp[xn] = ((mp_limb_t) i) << cnt; 54 /* Zero the xn lower limbs. */ 55 MPN_ZERO(xp, xn); 56 57 nbits = GMP_NUMB_BITS - cnt; 58 e += nbits; /* exponent _before_ the rounding */ 59 60 /* round if MPFR_PREC(x) smaller than length of i */ 61 if (MPFR_UNLIKELY (MPFR_PREC (x) < nbits) && 62 MPFR_UNLIKELY (mpfr_round_raw (xp + xn, xp + xn, nbits, 0, 63 MPFR_PREC (x), rnd_mode, &inex))) 64 { 65 e++; 66 xp[xn] = MPFR_LIMB_HIGHBIT; 67 } 68 69 MPFR_EXP (x) = e; 70 return mpfr_check_range (x, inex, rnd_mode); 71 } 72} 73