diff options
author | vlefevre <vlefevre@280ebfd0-de03-0410-8827-d642c229c3f4> | 2020-09-15 13:46:39 +0000 |
---|---|---|
committer | vlefevre <vlefevre@280ebfd0-de03-0410-8827-d642c229c3f4> | 2020-09-15 13:46:39 +0000 |
commit | 7e0cfe191be7a9354a78941af1aed68d95d0200d (patch) | |
tree | 380b0f6be0b18a39895d9651dbec5e3fdfd7b841 | |
parent | 01f58989238361e3622483c0f8f4ba58c924df3b (diff) | |
download | mpfr-7e0cfe191be7a9354a78941af1aed68d95d0200d.tar.gz |
[src/random_deviate.c] Fixed non-portable code.
(merged changesets r14123-14124 from the trunk)
git-svn-id: https://scm.gforge.inria.fr/anonscm/svn/mpfr/branches/4.1@14126 280ebfd0-de03-0410-8827-d642c229c3f4
-rw-r--r-- | src/random_deviate.c | 15 |
1 files changed, 12 insertions, 3 deletions
diff --git a/src/random_deviate.c b/src/random_deviate.c index 72531e774..c5242f79b 100644 --- a/src/random_deviate.c +++ b/src/random_deviate.c @@ -289,6 +289,7 @@ mpfr_random_deviate_value (int neg, unsigned long n, mpfr_random_size_t p = mpfr_get_prec (z); /* Number of bits in result */ mpz_t t; int inex; + mpfr_exp_t negxe; if (n == 0) { @@ -370,14 +371,22 @@ mpfr_random_deviate_value (int neg, unsigned long n, mpz_setbit (t, 0); /* Set the trailing bit so result is always inexact */ if (neg) mpz_neg (t, t); - /* Is -x->e representable as a mpfr_exp_t? */ - MPFR_ASSERTN (x->e <= (mpfr_uexp_t)(-1) >> 1); + /* Portable version of the negation of x->e, with a check of overflow. */ + if (MPFR_UNLIKELY (x->e > MPFR_EXP_MAX)) + { + /* Overflow, except when x->e = MPFR_EXP_MAX + 1 = - MPFR_EXP_MIN. */ + MPFR_ASSERTN (MPFR_EXP_MIN + MPFR_EXP_MAX == -1 && + x->e == (mpfr_random_size_t) MPFR_EXP_MAX + 1); + negxe = MPFR_EXP_MIN; + } + else + negxe = - (mpfr_exp_t) x->e; /* * Let mpfr_set_z_2exp do all the work of rounding to the requested * precision, setting overflow/underflow flags, and returning the right * inexact value. */ - inex = mpfr_set_z_2exp (z, t, -x->e, rnd); + inex = mpfr_set_z_2exp (z, t, negxe, rnd); mpz_clear (t); return inex; } |