summaryrefslogtreecommitdiff
path: root/set_d.c
diff options
context:
space:
mode:
authorpelissip <pelissip@280ebfd0-de03-0410-8827-d642c229c3f4>2004-01-28 14:22:05 +0000
committerpelissip <pelissip@280ebfd0-de03-0410-8827-d642c229c3f4>2004-01-28 14:22:05 +0000
commit0d0a6452168bfa99b9fef5808c81738245992bc0 (patch)
tree7adc2d00d0d52fd8c59f10349506fe5e1a3e727b /set_d.c
parent2f7d3ed598d3f6ec2925673ebc527d729a253576 (diff)
downloadmpfr-0d0a6452168bfa99b9fef5808c81738245992bc0.tar.gz
Better supports of non IEEE-754 floats (don't use anymore ieee_double_extract if _GMP_IEEE is not set).
git-svn-id: svn://scm.gforge.inria.fr/svn/mpfr/trunk@2650 280ebfd0-de03-0410-8827-d642c229c3f4
Diffstat (limited to 'set_d.c')
-rw-r--r--set_d.c29
1 files changed, 24 insertions, 5 deletions
diff --git a/set_d.c b/set_d.c
index 79cd23af9..f3c928617 100644
--- a/set_d.c
+++ b/set_d.c
@@ -1,7 +1,7 @@
/* mpfr_set_d -- convert a machine double precision float to
a multiple precision floating-point number
-Copyright 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+Copyright 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
This file is part of the MPFR Library.
@@ -155,19 +155,38 @@ mpfr_set_d (mpfr_ptr r, double d, mp_rnd_t rnd_mode)
mp_size_t i, k;
mpfr_t tmp;
mp_limb_t tmpmant[MPFR_LIMBS_PER_DOUBLE];
-
+
MPFR_CLEAR_FLAGS(r);
if (d == 0)
{
+#if _GMP_IEEE_FLOATS
union ieee_double_extract x;
MPFR_SET_ZERO(r);
/* set correct sign */
x.d = d;
- if (((x.s.sig == 1) && (MPFR_SIGN(r) > 0))
- || ((x.s.sig == 0) && (MPFR_SIGN(r) < 0)))
- MPFR_CHANGE_SIGN(r);
+ if (x.s.sig == 1)
+ MPFR_SET_NEG(r);
+ else
+ MPFR_SET_POS(r);
+#else /* _GMP_IEEE_FLOATS */
+ MPFR_SET_ZERO(r);
+ {
+ /* This is to get the sign of zero on non-IEEE hardware
+ Some systems support +0.0, -0.0 and unsigned zero.
+ We can't use d==+0.0 since it should be always true,
+ so we check that the memory representation of d is the
+ same than +0.0. etc */
+ double poszero = +0.0, negzero = -0.0;
+ if (memcmp(&d, &poszero, sizeof(double)) == 0)
+ MPFR_SET_POS(r);
+ else if (memcmp(&d, &negzero, sizeof(double)) == 0)
+ MPFR_SET_NEG(r);
+ else
+ MPFR_SET_POS(r);
+ }
+#endif
return 0; /* 0 is exact */
}
else if (DOUBLE_ISNAN(d))