diff options
author | vlefevre <vlefevre@280ebfd0-de03-0410-8827-d642c229c3f4> | 2002-12-10 22:23:04 +0000 |
---|---|---|
committer | vlefevre <vlefevre@280ebfd0-de03-0410-8827-d642c229c3f4> | 2002-12-10 22:23:04 +0000 |
commit | fe4c1c4fed9d7d45a1a8651c62c4e0c8b2e92636 (patch) | |
tree | 7db92889db6151f5391694029c56c2723a5338d2 /set_d.c | |
parent | 9c8417b79a22494ecf97f82eafe026591644c010 (diff) | |
download | mpfr-fe4c1c4fed9d7d45a1a8651c62c4e0c8b2e92636.tar.gz |
Patch by Torbjorn Granlund <tege@swox.com>: Don't use TMP_ allocation
mechanism for fixed size objects. Resulting streamlining. Misc
addressing changes to work around GNUPro bugs.
Patch by VL: Some other changes in mpfr_set_d.
git-svn-id: svn://scm.gforge.inria.fr/svn/mpfr/trunk@2111 280ebfd0-de03-0410-8827-d642c229c3f4
Diffstat (limited to 'set_d.c')
-rw-r--r-- | set_d.c | 38 |
1 files changed, 22 insertions, 16 deletions
@@ -160,12 +160,12 @@ __mpfr_extract_double (mp_ptr rp, double d) int mpfr_set_d (mpfr_ptr r, double d, mp_rnd_t rnd_mode) { - int signd, sizetmp, inexact; - unsigned int cnt, k; - mpfr_ptr tmp; - TMP_DECL(marker); + int signd, inexact; + unsigned int cnt; + mp_size_t i, k; + mpfr_t tmp; + mp_limb_t tmpmant[MPFR_LIMBS_PER_DOUBLE]; - TMP_MARK(marker); MPFR_CLEAR_FLAGS(r); if (d == 0) @@ -196,34 +196,40 @@ mpfr_set_d (mpfr_ptr r, double d, mp_rnd_t rnd_mode) /* warning: don't use tmp=r here, even if SIZE(r) >= MPFR_LIMBS_PER_DOUBLE, since PREC(r) may be different from PREC(tmp), and then both variables would have same precision in the mpfr_set4 call below. */ - tmp = (mpfr_ptr) TMP_ALLOC(sizeof(mpfr_t)); - MPFR_MANT(tmp) = TMP_ALLOC(MPFR_LIMBS_PER_DOUBLE * BYTES_PER_MP_LIMB); + MPFR_MANT(tmp) = tmpmant; MPFR_PREC(tmp) = 53; MPFR_SIZE(tmp) = MPFR_LIMBS_PER_DOUBLE; - sizetmp = MPFR_LIMBS_PER_DOUBLE; signd = (d < 0) ? -1 : 1; d = ABS (d); - MPFR_EXP(tmp) = __mpfr_extract_double (MPFR_MANT(tmp), d); + MPFR_EXP(tmp) = __mpfr_extract_double (tmpmant, d); - /* determine number k of zero high limbs */ - for (k = 0; k < sizetmp && MPFR_MANT(tmp)[sizetmp - 1 - k] == 0; k++); + /* determine the index i of the most significant non-zero limb + and the number k of zero high limbs */ + i = MPFR_LIMBS_PER_DOUBLE - 1; + k = 0; + while (tmpmant[i] == 0) + { + MPFR_ASSERTN(i > 0); + i--; + k++; + } - count_leading_zeros (cnt, MPFR_MANT(tmp)[sizetmp - 1 - k]); + count_leading_zeros (cnt, tmpmant[i]); if (cnt) - mpn_lshift (MPFR_MANT(tmp) + k, MPFR_MANT(tmp), sizetmp - k, cnt); + mpn_lshift (tmpmant + k, tmpmant, i + 1, cnt); else if (k) - MPN_COPY (MPFR_MANT(tmp) + k, MPFR_MANT(tmp), sizetmp - k); + MPN_COPY (tmpmant + k, tmpmant, i + 1); + if (k) - MPN_ZERO (MPFR_MANT(tmp), k); + MPN_ZERO (tmpmant, k); MPFR_EXP(tmp) -= cnt + k * BITS_PER_MP_LIMB; /* tmp is exact since PREC(tmp)=53 */ inexact = mpfr_set4 (r, tmp, rnd_mode, signd); - TMP_FREE(marker); return inexact; } |