summaryrefslogtreecommitdiff
path: root/get_d.c
diff options
context:
space:
mode:
authorpelissip <pelissip@280ebfd0-de03-0410-8827-d642c229c3f4>2005-01-04 10:28:41 +0000
committerpelissip <pelissip@280ebfd0-de03-0410-8827-d642c229c3f4>2005-01-04 10:28:41 +0000
commit26d8b432ae748ead83614ae6297ac6afe47ae6f5 (patch)
tree623daa1dd45c483226e7e048c49a414d805a99ce /get_d.c
parent84984a1a1ad27bd6a5ca600fcc655bebf3768893 (diff)
downloadmpfr-26d8b432ae748ead83614ae6297ac6afe47ae6f5.tar.gz
Optimize mpfr_get_d.
git-svn-id: svn://scm.gforge.inria.fr/svn/mpfr/trunk@3167 280ebfd0-de03-0410-8827-d642c229c3f4
Diffstat (limited to 'get_d.c')
-rw-r--r--get_d.c59
1 files changed, 33 insertions, 26 deletions
diff --git a/get_d.c b/get_d.c
index f3a9d1a22..96849e6bb 100644
--- a/get_d.c
+++ b/get_d.c
@@ -22,7 +22,6 @@ MA 02111-1307, USA. */
#include <float.h>
-
#define MPFR_NEED_LONGLONG_H
#include "mpfr-impl.h"
@@ -90,7 +89,7 @@ mpfr_scale2 (double d, int exp)
{
union ieee_double_extract x;
- if (MPFR_UNLIKELY(d == 1.0))
+ if (MPFR_UNLIKELY (d == 1.0))
{
d = 0.5;
exp ++;
@@ -102,7 +101,7 @@ mpfr_scale2 (double d, int exp)
MPFR_ASSERTD (-1073 <= exp && exp <= 1025);
x.d = d;
- if (MPFR_UNLIKELY(exp < -1021)) /* subnormal case */
+ if (MPFR_UNLIKELY (exp < -1021)) /* subnormal case */
{
x.s.exp += exp + 52;
x.d *= DBL_EPSILON;
@@ -113,7 +112,7 @@ mpfr_scale2 (double d, int exp)
}
return x.d;
}
-#else
+#else /* _GMP_IEEE_FLOATS */
{
double factor;
@@ -151,30 +150,32 @@ mpfr_scale2 (double d, int exp)
such as NaN must be avoided if not supported). */
double
-mpfr_get_d3 (mpfr_srcptr src, mp_exp_t e, mp_rnd_t rnd_mode)
+mpfr_get_d (mpfr_srcptr src, mp_rnd_t rnd_mode)
{
double d;
int negative;
+ mp_exp_t e;
- if (MPFR_UNLIKELY(MPFR_IS_SINGULAR(src)))
+ if (MPFR_UNLIKELY (MPFR_IS_SINGULAR (src)))
{
- if (MPFR_IS_NAN(src))
+ if (MPFR_IS_NAN (src))
return MPFR_DBL_NAN;
negative = MPFR_IS_NEG (src);
- if (MPFR_IS_INF(src))
+ if (MPFR_IS_INF (src))
return negative ? MPFR_DBL_INFM : MPFR_DBL_INFP;
MPFR_ASSERTD (MPFR_IS_ZERO(src));
return negative ? -0.0 : 0.0;
}
-
+
+ e = MPFR_GET_EXP (src);
negative = MPFR_IS_NEG (src);
-
+
/* the smallest normalized number is 2^(-1022)=0.1e-1021, and the smallest
subnormal is 2^(-1074)=0.1e-1073 */
- if (MPFR_UNLIKELY(e < -1073))
+ if (MPFR_UNLIKELY (e < -1073))
{
/* Note: Avoid using a constant expression DBL_MIN * DBL_EPSILON
as this gives 0 instead of the correct result with gcc on some
@@ -190,7 +191,7 @@ mpfr_get_d3 (mpfr_srcptr src, mp_exp_t e, mp_rnd_t rnd_mode)
d *= DBL_EPSILON;
}
/* the largest normalized number is 2^1024*(1-2^(-53))=0.111...111e1024 */
- else if (MPFR_UNLIKELY(e > 1024))
+ else if (MPFR_UNLIKELY (e > 1024))
{
d = negative ?
(rnd_mode == GMP_RNDZ || rnd_mode == GMP_RNDU ?
@@ -206,7 +207,7 @@ mpfr_get_d3 (mpfr_srcptr src, mp_exp_t e, mp_rnd_t rnd_mode)
int carry;
nbits = IEEE_DBL_MANT_DIG; /* 53 */
- if (MPFR_UNLIKELY(e < -1021))
+ if (MPFR_UNLIKELY (e < -1021))
/*In the subnormal case, compute the exact number of significant bits*/
{
nbits += (1021 + e);
@@ -236,21 +237,11 @@ mpfr_get_d3 (mpfr_srcptr src, mp_exp_t e, mp_rnd_t rnd_mode)
return d;
}
-/* Note: do not read the exponent if it has no meaning (avoid possible
- traps on some implementations). */
-
-double
-mpfr_get_d (mpfr_srcptr src, mp_rnd_t rnd_mode)
-{
- return mpfr_get_d3 (src, MPFR_IS_PURE_FP(src) ?
- MPFR_GET_EXP (src) : 0, rnd_mode);
-}
-
+#undef mpfr_get_d1
double
mpfr_get_d1 (mpfr_srcptr src)
{
- return mpfr_get_d3 (src, MPFR_IS_PURE_FP(src) ? MPFR_GET_EXP (src) : 0,
- __gmpfr_default_rounding_mode);
+ return mpfr_get_d (src, __gmpfr_default_rounding_mode);
}
double
@@ -258,8 +249,24 @@ mpfr_get_d_2exp (long *expptr, mpfr_srcptr src, mp_rnd_t rnd_mode)
{
double ret;
mp_exp_t exp;
+ mpfr_t tmp;
+
+ if (MPFR_UNLIKELY (MPFR_IS_SINGULAR (src)))
+ {
+ int negative;
+ *expptr = 0;
+ if (MPFR_IS_NAN (src))
+ return MPFR_DBL_NAN;
+ negative = MPFR_IS_NEG (src);
+ if (MPFR_IS_INF (src))
+ return negative ? MPFR_DBL_INFM : MPFR_DBL_INFP;
+ MPFR_ASSERTD (MPFR_IS_ZERO(src));
+ return negative ? -0.0 : 0.0;
+ }
- ret = mpfr_get_d3 (src, 0, rnd_mode);
+ tmp[0] = *src; /* Hack copy mpfr_t */
+ MPFR_SET_EXP (tmp, 0);
+ ret = mpfr_get_d (tmp, rnd_mode);
if (MPFR_IS_PURE_FP(src))
{