summaryrefslogtreecommitdiff
path: root/set_d.c
diff options
context:
space:
mode:
authorvlefevre <vlefevre@280ebfd0-de03-0410-8827-d642c229c3f4>2002-12-10 22:23:04 +0000
committervlefevre <vlefevre@280ebfd0-de03-0410-8827-d642c229c3f4>2002-12-10 22:23:04 +0000
commitfe4c1c4fed9d7d45a1a8651c62c4e0c8b2e92636 (patch)
tree7db92889db6151f5391694029c56c2723a5338d2 /set_d.c
parent9c8417b79a22494ecf97f82eafe026591644c010 (diff)
downloadmpfr-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.c38
1 files changed, 22 insertions, 16 deletions
diff --git a/set_d.c b/set_d.c
index 02e922374..2605d1a99 100644
--- a/set_d.c
+++ b/set_d.c
@@ -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;
}