summaryrefslogtreecommitdiff
path: root/mpz/get_d_2exp.c
diff options
context:
space:
mode:
authorKevin Ryde <user42@zip.com.au>2003-07-14 00:27:44 +0200
committerKevin Ryde <user42@zip.com.au>2003-07-14 00:27:44 +0200
commite050b971bd45fb794efdd4a3cbc296ff73ee4bc4 (patch)
treef7f08238dec16902e19354bd8b1b3411cee4914c /mpz/get_d_2exp.c
parenta12466680dfc8161584926778b182295e799c194 (diff)
downloadgmp-e050b971bd45fb794efdd4a3cbc296ff73ee4bc4.tar.gz
* mpz/get_d.c, mpz/get_d_2exp.c, mpf/get_d.c, mpf/get_d_2exp.c: Use
mpn_get_d.
Diffstat (limited to 'mpz/get_d_2exp.c')
-rw-r--r--mpz/get_d_2exp.c27
1 files changed, 9 insertions, 18 deletions
diff --git a/mpz/get_d_2exp.c b/mpz/get_d_2exp.c
index d005b05e9..adc254950 100644
--- a/mpz/get_d_2exp.c
+++ b/mpz/get_d_2exp.c
@@ -27,32 +27,23 @@ double
mpz_get_d_2exp (signed long int *exp2, mpz_srcptr src)
{
double res;
- mp_size_t size, i, n_limbs_to_use;
- int negative;
- mp_ptr qp;
+ mp_size_t size, abs_size;
+ mp_srcptr ptr;
int cnt;
long exp;
size = SIZ(src);
- if (size == 0)
+ if (UNLIKELY (size == 0))
{
*exp2 = 0;
return 0.0;
}
- negative = size < 0;
- size = ABS (size);
- qp = PTR(src);
-
- n_limbs_to_use = MIN (LIMBS_PER_DOUBLE, size);
- qp += size - n_limbs_to_use;
- res = qp[0] / MP_BASE_AS_DOUBLE;
- for (i = 1; i < n_limbs_to_use; i++)
- res = (res + qp[i]) / MP_BASE_AS_DOUBLE;
- count_leading_zeros (cnt, qp[n_limbs_to_use - 1]);
- cnt -= GMP_NAIL_BITS;
- exp = size * GMP_NUMB_BITS - cnt;
- res = res * ((mp_limb_t) 1 << cnt);
+ ptr = PTR(src);
+ abs_size = ABS(size);
+ count_leading_zeros (cnt, ptr[abs_size - 1]);
+ exp = abs_size * GMP_NUMB_BITS - (cnt - GMP_NAIL_BITS);
+ res = mpn_get_d (ptr, abs_size, (mp_size_t) 0, -exp);
/* gcc on m68k and x86 holds floats in the coprocessor, which may mean
"res" has extra precision. Force it through memory to ensure any
@@ -73,5 +64,5 @@ mpz_get_d_2exp (signed long int *exp2, mpz_srcptr src)
ASSERT (res < 1.0);
*exp2 = exp;
- return negative ? -res : res;
+ return (size >= 0 ? res : -res);
}