summaryrefslogtreecommitdiff
path: root/mpfr.c
diff options
context:
space:
mode:
authorArnold D. Robbins <arnold@skeeve.com>2016-08-01 22:53:51 +0300
committerArnold D. Robbins <arnold@skeeve.com>2016-08-01 22:53:51 +0300
commit9698fd1ebff2bc3f76efbf498c28ce21aa515b7e (patch)
tree82d4d368ede5133d2eff3c7d535274c1f7eddccf /mpfr.c
parentde23ab7bfbea6ee03ef7386c6c203a4b2b7b7116 (diff)
parent385636c3da7f36ae020eeb7098485923168ccf4b (diff)
downloadgawk-9698fd1ebff2bc3f76efbf498c28ce21aa515b7e.tar.gz
Merge branch 'gawk-4.1-stable'
Diffstat (limited to 'mpfr.c')
-rw-r--r--mpfr.c22
1 files changed, 17 insertions, 5 deletions
diff --git a/mpfr.c b/mpfr.c
index 0bb5b435..673553df 100644
--- a/mpfr.c
+++ b/mpfr.c
@@ -39,6 +39,8 @@ mpz_t MFNR;
bool do_ieee_fmt; /* IEEE-754 floating-point emulation */
mpfr_rnd_t ROUND_MODE;
+static mpfr_prec_t default_prec;
+
static mpfr_rnd_t get_rnd_mode(const char rmode);
static NODE *mpg_force_number(NODE *n);
static NODE *mpg_make_number(double);
@@ -70,7 +72,7 @@ static inline mpfr_ptr mpg_tofloat(mpfr_ptr mf, mpz_ptr mz);
void
init_mpfr(mpfr_prec_t prec, const char *rmode)
{
- mpfr_set_default_prec(prec);
+ mpfr_set_default_prec(default_prec = prec);
ROUND_MODE = get_rnd_mode(rmode[0]);
mpfr_set_default_rounding_mode(ROUND_MODE);
make_number = mpg_make_number;
@@ -556,7 +558,7 @@ set_PREC()
}
if (prec > 0)
- mpfr_set_default_prec(prec);
+ mpfr_set_default_prec(default_prec = prec);
}
@@ -700,6 +702,7 @@ do_mpfr_func(const char *name,
NODE *t1, *res;
mpfr_ptr p1;
int tval;
+ mpfr_prec_t argprec;
t1 = POP_SCALAR();
if (do_lint && (fixtype(t1)->flags & NUMBER) == 0)
@@ -708,7 +711,8 @@ do_mpfr_func(const char *name,
force_number(t1);
p1 = MP_FLOAT(t1);
res = mpg_float();
- mpfr_set_prec(res->mpg_numbr, mpfr_get_prec(p1)); /* needed at least for sqrt() */
+ if ((argprec = mpfr_get_prec(p1)) > default_prec)
+ mpfr_set_prec(res->mpg_numbr, argprec); /* needed at least for sqrt() */
tval = mpfr_func(res->mpg_numbr, p1, ROUND_MODE);
IEEE_FMT(res->mpg_numbr, tval);
DEREF(t1);
@@ -1295,9 +1299,17 @@ mpg_tofloat(mpfr_ptr mf, mpz_ptr mz)
prec -= (size_t) mpz_scan1(mz, 0); /* least significant 1 bit index starting at 0 */
if (prec > MPFR_PREC_MAX)
prec = MPFR_PREC_MAX;
- if (prec > PRECISION_MIN)
- mpfr_set_prec(mf, prec);
+ else if (prec < PRECISION_MIN)
+ prec = PRECISION_MIN;
}
+ else
+ prec = PRECISION_MIN;
+ /*
+ * Always set the precision to avoid hysteresis, since do_mpfr_func
+ * may copy our precision.
+ */
+ if (prec != mpfr_get_prec(mf))
+ mpfr_set_prec(mf, prec);
mpfr_set_z(mf, mz, ROUND_MODE);
return mf;