summaryrefslogtreecommitdiff
path: root/get_f.c
diff options
context:
space:
mode:
authorvlefevre <vlefevre@280ebfd0-de03-0410-8827-d642c229c3f4>2006-01-13 15:28:51 +0000
committervlefevre <vlefevre@280ebfd0-de03-0410-8827-d642c229c3f4>2006-01-13 15:28:51 +0000
commit976948dfac2e4ae6a993b0244e331ab1a62c6375 (patch)
tree601c35f693825ef36a1e41fe06f0b1c41d46e21f /get_f.c
parenteb16e3c8082b7aa0ceafbc0546c52b271f6bac48 (diff)
downloadmpfr-976948dfac2e4ae6a993b0244e331ab1a62c6375.tar.gz
Fixed bug in mpfr_get_f and added testcases (merges from the trunk:
-r3977:3978 and -r4001:4002 for get_f.c; -r3977:3978 and -r3998:4001 for tests/tget_f.c). git-svn-id: svn://scm.gforge.inria.fr/svn/mpfr/branches/2.2@4003 280ebfd0-de03-0410-8827-d642c229c3f4
Diffstat (limited to 'get_f.c')
-rw-r--r--get_f.c33
1 files changed, 16 insertions, 17 deletions
diff --git a/get_f.c b/get_f.c
index c3d62bca9..bc5183e39 100644
--- a/get_f.c
+++ b/get_f.c
@@ -27,8 +27,9 @@ MA 02110-1301, USA. */
int
mpfr_get_f (mpf_ptr x, mpfr_srcptr y, mp_rnd_t rnd_mode)
{
- unsigned long sx, sy, precx, precy, sh;
- mp_exp_t ey;
+ mp_size_t sx, sy;
+ mp_prec_t precx, precy;
+ int sh;
if (MPFR_UNLIKELY(MPFR_IS_SINGULAR(y)))
{
@@ -44,20 +45,18 @@ mpfr_get_f (mpf_ptr x, mpfr_srcptr y, mp_rnd_t rnd_mode)
sx = PREC(x); /* number of limbs of the mantissa of x */
precy = MPFR_PREC(y);
- precx = sx * BITS_PER_MP_LIMB;
- sy = 1 + (MPFR_PREC(y) - 1) / BITS_PER_MP_LIMB;
+ precx = (mp_prec_t) sx * BITS_PER_MP_LIMB;
+ sy = MPFR_LIMB_SIZE (y);
/* since mpf numbers are represented in base 2^BITS_PER_MP_LIMB,
we loose -EXP(y) % BITS_PER_MP_LIMB bits in the most significant limb */
- ey = MPFR_GET_EXP(y) % BITS_PER_MP_LIMB;
- if (ey <= 0)
- sh = (unsigned long) (-ey);
- else /* 0 < ey < BITS_PER_MP_LIMB */
- sh = BITS_PER_MP_LIMB - (unsigned long) ey;
+ sh = MPFR_GET_EXP(y) % BITS_PER_MP_LIMB;
+ sh = sh <= 0 ? - sh : BITS_PER_MP_LIMB - sh;
+ MPFR_ASSERTD (sh >= 0);
if (precy + sh <= precx) /* we can copy directly */
{
- /* necessarily sy <= sx */
- if (sh)
+ MPFR_ASSERTN (sx >= sy);
+ if (sh != 0)
mpn_rshift (PTR(x) + sx - sy, MPFR_MANT(y), sy, sh);
else
MPN_COPY (PTR(x) + sx - sy, MPFR_MANT(y), sy);
@@ -68,17 +67,17 @@ mpfr_get_f (mpf_ptr x, mpfr_srcptr y, mp_rnd_t rnd_mode)
else /* we have to round to precx - sh bits */
{
mpfr_t z;
- unsigned long sz;
+ mp_size_t sz;
mpfr_init2 (z, precx - sh);
- sz = 1 + (MPFR_PREC(z) - 1) / BITS_PER_MP_LIMB;
+ sz = MPFR_LIMB_SIZE (z);
mpfr_set (z, y, rnd_mode);
/* warning, sh may change due to rounding, but then z is a power of two,
thus we can safely ignore its last bit which is 0 */
- ey = MPFR_GET_EXP(z) % BITS_PER_MP_LIMB;
- sh = (ey <= 0) ? (unsigned long) (-ey)
- : BITS_PER_MP_LIMB - (unsigned long) ey;
- if (sh)
+ sh = MPFR_GET_EXP(z) % BITS_PER_MP_LIMB;
+ sh = sh <= 0 ? - sh : BITS_PER_MP_LIMB - sh;
+ MPFR_ASSERTD (sh >= 0);
+ if (sh != 0)
mpn_rshift (PTR(x) + sx - sz, MPFR_MANT(z), sz, sh);
else
MPN_COPY (PTR(x) + sx - sz, MPFR_MANT(z), sz);