1 /* mpfr_set_q -- set a floating-point number from a multiple-precision rational
3 Copyright 2000, 2001, 2002, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
4 Contributed by the Arenaire and Caramel projects, INRIA.
6 This file is part of the GNU MPFR Library.
8 The GNU MPFR Library is free software; you can redistribute it and/or modify
9 it under the terms of the GNU Lesser General Public License as published by
10 the Free Software Foundation; either version 3 of the License, or (at your
11 option) any later version.
13 The GNU MPFR Library is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
15 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
16 License for more details.
18 You should have received a copy of the GNU Lesser General Public License
19 along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
20 http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
21 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
23 #define MPFR_NEED_LONGLONG_H
24 #include "mpfr-impl.h"
27 * Set f to z, choosing the smallest precision for f
28 * so that z = f*(2^BPML)*zs*2^(RetVal)
31 set_z (mpfr_ptr f, mpz_srcptr z, mp_size_t *zs)
38 MPFR_ASSERTD (mpz_sgn (z) != 0);
40 /* Remove useless ending 0 */
41 for (p = PTR (z), s = *zs = ABS (SIZ (z)) ; *p == 0; p++, s--)
42 MPFR_ASSERTD (s >= 0);
44 /* Get working precision */
45 count_leading_zeros (c, p[s-1]);
46 pf = s * GMP_NUMB_BITS - c;
47 if (pf < MPFR_PREC_MIN)
53 mpn_lshift (MPFR_MANT (f), p, s, c);
55 MPN_COPY (MPFR_MANT (f), p, s);
57 MPFR_SET_SIGN (f, mpz_sgn (z));
63 /* set f to the rational q */
65 mpfr_set_q (mpfr_ptr f, mpq_srcptr q, mpfr_rnd_t rnd)
73 MPFR_SAVE_EXPO_DECL (expo);
77 /* NAN and INF for mpq are not really documented, but could be found */
78 if (MPFR_UNLIKELY (mpz_sgn (num) == 0))
80 if (MPFR_UNLIKELY (mpz_sgn (den) == 0))
92 if (MPFR_UNLIKELY (mpz_sgn (den) == 0))
95 MPFR_SET_SIGN (f, mpz_sgn (num));
99 MPFR_SAVE_EXPO_MARK (expo);
101 cn = set_z (n, num, &sn);
102 cd = set_z (d, den, &sd);
105 if (MPFR_UNLIKELY (sn > MPFR_EMAX_MAX / GMP_NUMB_BITS))
107 inexact = mpfr_overflow (f, rnd, MPFR_SIGN (f));
110 if (MPFR_UNLIKELY (sn < MPFR_EMIN_MIN / GMP_NUMB_BITS -1))
112 if (rnd == MPFR_RNDN)
114 inexact = mpfr_underflow (f, rnd, MPFR_SIGN (f));
118 inexact = mpfr_div (f, n, d, rnd);
119 shift = GMP_NUMB_BITS*sn+cn-cd;
120 MPFR_ASSERTD (shift == GMP_NUMB_BITS*sn+cn-cd);
121 cd = mpfr_mul_2si (f, f, shift, rnd);
122 MPFR_SAVE_EXPO_FREE (expo);
123 if (MPFR_UNLIKELY (cd != 0))
126 inexact = mpfr_check_range (f, inexact, rnd);