summaryrefslogtreecommitdiff
path: root/src/exp_2.c
diff options
context:
space:
mode:
authorzimmerma <zimmerma@280ebfd0-de03-0410-8827-d642c229c3f4>2018-09-05 10:20:36 +0000
committerzimmerma <zimmerma@280ebfd0-de03-0410-8827-d642c229c3f4>2018-09-05 10:20:36 +0000
commit4e895d89500fe926a7e0e992670b1e2fabb25e10 (patch)
tree590b77098cfc4d1af08aa991b73a20fbfa786550 /src/exp_2.c
parent5f3039ca80f175e4c3e055b39d9e3f0f5a1236da (diff)
downloadmpfr-4e895d89500fe926a7e0e992670b1e2fabb25e10.tar.gz
[src/exp_2.c] fix for 16-bit limb
[tests/texp.c] improve error message git-svn-id: svn://scm.gforge.inria.fr/svn/mpfr/trunk@13135 280ebfd0-de03-0410-8827-d642c229c3f4
Diffstat (limited to 'src/exp_2.c')
-rw-r--r--src/exp_2.c40
1 files changed, 37 insertions, 3 deletions
diff --git a/src/exp_2.c b/src/exp_2.c
index 06d2e9d52..316b3d555 100644
--- a/src/exp_2.c
+++ b/src/exp_2.c
@@ -33,6 +33,42 @@ mpz_normalize (mpz_t, mpz_t, mpfr_exp_t);
static mpfr_exp_t
mpz_normalize2 (mpz_t, mpz_t, mpfr_exp_t, mpfr_exp_t);
+/* count the number of significant bits of n, i.e.,
+ nbits(unsigned long) - count_leading_zeros (n) */
+static int
+nbits_ulong (unsigned long n)
+{
+ int nbits = 0;
+
+ MPFR_ASSERTD (n > 0);
+ while (n >= 0x10000)
+ {
+ n >>= 16;
+ nbits += 16;
+ }
+ MPFR_ASSERTD (n <= 0xffff);
+ if (n >= 0x100)
+ {
+ n >>= 8;
+ nbits += 8;
+ }
+ MPFR_ASSERTD (n <= 0xff);
+ if (n >= 0x10)
+ {
+ n >>= 4;
+ nbits += 4;
+ }
+ MPFR_ASSERTD (n <= 0xf);
+ if (n >= 4)
+ {
+ n >>= 2;
+ nbits += 2;
+ }
+ MPFR_ASSERTD (n <= 3);
+ /* now n = 1, 2, or 3 */
+ return nbits + 1 + (n >= 2);
+}
+
/* if k = the number of bits of z > q, divides z by 2^(k-q) and returns k-q.
Otherwise do nothing and return 0.
*/
@@ -146,9 +182,7 @@ mpfr_exp_2 (mpfr_ptr y, mpfr_srcptr x, mpfr_rnd_t rnd_mode)
error_r = 0;
else
{
- count_leading_zeros (error_r,
- (mp_limb_t) SAFE_ABS (unsigned long, n) + 1);
- error_r = GMP_NUMB_BITS - error_r;
+ error_r = nbits_ulong (SAFE_ABS (unsigned long, n) + 1);
/* we have |x| <= 2^error_r * log(2) */
}