1
/* mpfr_set_q -- set a floating-point number from a multiple-precision rational
3
Copyright 2000, 2001, 2002, 2004, 2005 Free Software Foundation, Inc.
5
This file is part of the MPFR Library.
7
The MPFR Library is free software; you can redistribute it and/or modify
8
it under the terms of the GNU Lesser General Public License as published by
9
the Free Software Foundation; either version 2.1 of the License, or (at your
10
option) any later version.
12
The MPFR Library is distributed in the hope that it will be useful, but
13
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
15
License for more details.
17
You should have received a copy of the GNU Lesser General Public License
18
along with the MPFR Library; see the file COPYING.LIB. If not, write to
19
the Free Software Foundation, Inc., 51 Franklin Place, Fifth Floor, Boston,
20
MA 02110-1301, USA. */
22
#define MPFR_NEED_LONGLONG_H
23
#include "mpfr-impl.h"
26
* Set f to z, choosing the smallest precision for f
27
* so that z = f*(2^BPML)*zs*2^(RetVal)
30
set_z (mpfr_ptr f, mpz_srcptr z, mp_size_t *zs)
37
MPFR_ASSERTD (mpz_sgn (z) != 0);
39
/* Remove useless ending 0 */
40
for (p = PTR (z), s = *zs = ABS (SIZ (z)) ; *p == 0; p++, s--)
41
MPFR_ASSERTD (s >= 0);
43
/* Get working precision */
44
count_leading_zeros (c, p[s-1]);
45
pf = s * BITS_PER_MP_LIMB - c;
46
if (pf < MPFR_PREC_MIN)
52
mpn_lshift (MPFR_MANT (f), p, s, c);
54
MPN_COPY (MPFR_MANT (f), p, s);
56
MPFR_SET_SIGN (f, mpz_sgn (z));
62
/* set f to the rational q */
64
mpfr_set_q (mpfr_ptr f, mpq_srcptr q, mp_rnd_t rnd)
72
MPFR_SAVE_EXPO_DECL (expo);
76
/* NAN and INF for mpq are not really documented, but could be found */
77
if (MPFR_UNLIKELY (mpz_sgn (num) == 0))
79
if (MPFR_UNLIKELY (mpz_sgn (den) == 0))
91
if (MPFR_UNLIKELY (mpz_sgn (den) == 0))
94
MPFR_SET_SIGN (f, mpz_sgn (num));
98
MPFR_SAVE_EXPO_MARK (expo);
100
cn = set_z (n, num, &sn);
101
cd = set_z (d, den, &sd);
104
if (MPFR_UNLIKELY (sn > MPFR_EMAX_MAX / BITS_PER_MP_LIMB))
106
inexact = mpfr_overflow (f, rnd, MPFR_SIGN (f));
109
if (MPFR_UNLIKELY (sn < MPFR_EMIN_MIN / BITS_PER_MP_LIMB -1))
113
inexact = mpfr_underflow (f, rnd, MPFR_SIGN (f));
117
inexact = mpfr_div (f, n, d, rnd);
118
shift = BITS_PER_MP_LIMB*sn+cn-cd;
119
MPFR_ASSERTD (shift == BITS_PER_MP_LIMB*sn+cn-cd);
120
cd = mpfr_mul_2si (f, f, shift, rnd);
121
MPFR_SAVE_EXPO_FREE (expo);
122
if (MPFR_UNLIKELY (cd != 0))
125
inexact = mpfr_check_range (f, inexact, rnd);