diff options
author | zimmerma <zimmerma@280ebfd0-de03-0410-8827-d642c229c3f4> | 2004-02-17 10:02:29 +0000 |
---|---|---|
committer | zimmerma <zimmerma@280ebfd0-de03-0410-8827-d642c229c3f4> | 2004-02-17 10:02:29 +0000 |
commit | a7604a09377bba7969c7dc861aee4d3008d77207 (patch) | |
tree | 9f98eb1967bbe910eb30f0552b468e64349571ab /set_f.c | |
parent | a670e9bc4c691d692b4c967758d1caa130d043ff (diff) | |
download | mpfr-a7604a09377bba7969c7dc861aee4d3008d77207.tar.gz |
fixed 2 bugs and added test
git-svn-id: svn://scm.gforge.inria.fr/svn/mpfr/trunk@2743 280ebfd0-de03-0410-8827-d642c229c3f4
Diffstat (limited to 'set_f.c')
-rw-r--r-- | set_f.c | 26 |
1 files changed, 15 insertions, 11 deletions
@@ -28,10 +28,10 @@ mpfr_set_f (mpfr_ptr y, mpf_srcptr x, mp_rnd_t rnd_mode) { mp_limb_t *my, *mx, *tmp; unsigned long cnt, sx, sy; - int inexact; + int inexact, carry = 0; TMP_DECL(marker); - if (SIZ(x) * MPFR_SIGN(y) < 0) + if (SIZ(x) * MPFR_FROM_SIGN_TO_INT(MPFR_SIGN(y)) < 0) MPFR_CHANGE_SIGN (y); MPFR_CLEAR_FLAGS (y); @@ -46,7 +46,7 @@ mpfr_set_f (mpfr_ptr y, mpf_srcptr x, mp_rnd_t rnd_mode) MPFR_SET_ZERO(y); return 0; /* 0 is exact */ } - + count_leading_zeros(cnt, mx[sx - 1]); if (sy <= sx) /* we may have to round even when sy = sx */ @@ -54,27 +54,31 @@ mpfr_set_f (mpfr_ptr y, mpf_srcptr x, mp_rnd_t rnd_mode) unsigned long xprec = sx * BITS_PER_MP_LIMB; TMP_MARK(marker); - tmp = (mp_limb_t*) TMP_ALLOC(xprec); + tmp = (mp_limb_t*) TMP_ALLOC(sx * BYTES_PER_MP_LIMB); if (cnt) - mpn_lshift(tmp, mx, sx, cnt); + mpn_lshift (tmp, mx, sx, cnt); else - MPN_COPY(tmp, mx, sx); - mpfr_round_raw (my, tmp, xprec, (SIZ(x)<0), MPFR_PREC(y), rnd_mode, - &inexact); + /* FIXME: we may avoid the copy here, and directly call mpfr_round_raw + on mx instead of tmp */ + MPN_COPY (tmp, mx, sx); + carry = mpfr_round_raw (my, tmp, xprec, (SIZ(x) < 0), MPFR_PREC(y), + rnd_mode, &inexact); + if (MPFR_UNLIKELY(carry)) /* result is a power of two */ + my[sy - 1] = MPFR_LIMB_HIGHBIT; TMP_FREE(marker); } else { if (cnt) - mpn_lshift(my + sy - sx, mx, sx, cnt); + mpn_lshift (my + sy - sx, mx, sx, cnt); else - MPN_COPY(my + sy - sx, mx, sy); + MPN_COPY (my + sy - sx, mx, sx); MPN_ZERO(my, sy - sx); /* no rounding necessary, since y has a larger mantissa */ inexact = 0; } - MPFR_SET_EXP(y, EXP(x) * BITS_PER_MP_LIMB - cnt); + MPFR_SET_EXP(y, EXP(x) * BITS_PER_MP_LIMB - cnt + carry); return inexact; } |