summaryrefslogtreecommitdiff
path: root/mpf/get_d.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 /mpf/get_d.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 'mpf/get_d.c')
-rw-r--r--mpf/get_d.c41
1 files changed, 8 insertions, 33 deletions
diff --git a/mpf/get_d.c b/mpf/get_d.c
index 9e736632e..3139e5cdd 100644
--- a/mpf/get_d.c
+++ b/mpf/get_d.c
@@ -1,6 +1,6 @@
/* double mpf_get_d (mpf_t src) -- Return the double approximation to SRC.
-Copyright 1996, 2001, 2002 Free Software Foundation, Inc.
+Copyright 1996, 2001, 2002, 2003 Free Software Foundation, Inc.
This file is part of the GNU MP Library.
@@ -22,42 +22,17 @@ MA 02111-1307, USA. */
#include "gmp.h"
#include "gmp-impl.h"
-/* HPPA 8000, 8200, 8500, and 8600 traps FCNV,UDW,DBL for values >= 2^63. This
- makes it slow. Worse, the Linux kernel apparently uses untested code in its
- trap handling routines, and gets the sign wrong. Their compiler port
- doesn't define __hppa as it should. Here is a workaround: */
-#if (defined (__hppa) || defined (__hppa__)) && GMP_LIMB_BITS == 64
-#define limb2dbl(limb) \
- ((limb) >> (GMP_LIMB_BITS - 1) != 0 \
- ? 2.0 * (double) (mp_limb_signed_t) (((limb) >> 1) | ((limb) & 1)) \
- : (double) (mp_limb_signed_t) (limb))
-#else
-#define limb2dbl(limb) \
- (double) (limb)
-#endif
-
double
mpf_get_d (mpf_srcptr src)
{
- double res;
- mp_size_t size, i, n_limbs_to_use;
- int negative;
- mp_ptr qp;
+ mp_size_t size, abs_size;
+ long exp;
- size = SIZ(src);
- if (size == 0)
+ size = SIZ (src);
+ if (UNLIKELY (size == 0))
return 0.0;
- negative = size < 0;
- size = ABS (size);
- qp = PTR(src);
-
- res = limb2dbl (qp[size - 1]);
- n_limbs_to_use = MIN (LIMBS_PER_DOUBLE, size);
- for (i = 2; i <= n_limbs_to_use; i++)
- res = res * MP_BASE_AS_DOUBLE + limb2dbl (qp[size - i]);
-
- res = __gmp_scale2 (res, (EXP(src) - n_limbs_to_use) * GMP_NUMB_BITS);
-
- return negative ? -res : res;
+ abs_size = ABS (size);
+ exp = (EXP (src) - abs_size) * GMP_NUMB_BITS;
+ return mpn_get_d (PTR (src), abs_size, size, exp);
}