summaryrefslogtreecommitdiff
path: root/get_d.c
diff options
context:
space:
mode:
authorryde <ryde@280ebfd0-de03-0410-8827-d642c229c3f4>2003-06-24 23:55:52 +0000
committerryde <ryde@280ebfd0-de03-0410-8827-d642c229c3f4>2003-06-24 23:55:52 +0000
commit425b32ae44489a80e2817e62e0ea4e96c3d17d0f (patch)
tree8a8b17c9903ddbfba0fbf2a3d390b4e35a1f150b /get_d.c
parent9299267f4dc820531b9527d81ff7eaf8411c8077 (diff)
downloadmpfr-425b32ae44489a80e2817e62e0ea4e96c3d17d0f.tar.gz
(MPFR_DBL_INFP, MPFR_DBL_INFM, MPFR_DBL_NAN): Make private
definitions based on IEEE byte sequences, in particular avoid HUGE_VAL from mpfr-math.h since that's not infinity on hppa1.1-hp-hpux10. Remove includes of mpfr-math.h, math.h and stddef.h. git-svn-id: svn://scm.gforge.inria.fr/svn/mpfr/trunk@2367 280ebfd0-de03-0410-8827-d642c229c3f4
Diffstat (limited to 'get_d.c')
-rw-r--r--get_d.c66
1 files changed, 55 insertions, 11 deletions
diff --git a/get_d.c b/get_d.c
index 8631ebb2c..01ab28865 100644
--- a/get_d.c
+++ b/get_d.c
@@ -20,27 +20,59 @@ along with the MPFR Library; see the file COPYING.LIB. If not, write to
the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
MA 02111-1307, USA. */
-#include <stddef.h> /* needed before math.h by gcc 3.2 on hppa2.0w hpux11 */
-
#include <float.h>
-/* For developers: Compile with -DNO_MATH_DEFS to test the alternate
- macros NAN... defined in mpfr-math.h */
-#ifndef NO_MATH_DEFS
-#include <math.h>
-#endif
-
#include "gmp.h"
#include "gmp-impl.h"
#include "longlong.h"
#include "mpfr.h"
#include "mpfr-impl.h"
-#include "mpfr-math.h"
+
static double mpfr_scale2 _PROTO ((double, int));
#define IEEE_DBL_MANT_DIG 53
+
+/* "double" NaN and infinities are written as explicit bytes to be sure of
+ getting what we want, and to be sure of not depending on libm.
+
+ Could use 4-byte "float" values and let the code convert them, but it
+ seems more direct to give exactly what we want. Certainly for gcc 3.0.2
+ on alphaev56-unknown-freebsd4.3 the NaN must be 8-bytes, since that
+ compiler+system was seen incorrectly converting from a "float" NaN. */
+
+#if _GMP_IEEE_FLOATS
+/* The "d" field guarantees alignment to a suitable boundary for a double.
+ Could use a union instead, if we checked the compiler supports union
+ initializers. */
+struct dbl_bytes {
+ unsigned char b[8];
+ double d;
+};
+
+#define MPFR_DBL_INFP (* (double *) dbl_infp.b)
+#define MPFR_DBL_INFM (* (double *) dbl_infm.b)
+#define MPFR_DBL_NAN (* (double *) dbl_nan.b)
+
+#if HAVE_DOUBLE_IEEE_LITTLE_ENDIAN
+static struct dbl_bytes dbl_infp = { { 0, 0, 0, 0, 0, 0, 0xF0, 0x7F } };
+static struct dbl_bytes dbl_infm = { { 0, 0, 0, 0, 0, 0, 0xF0, 0xFF } };
+static struct dbl_bytes dbl_nan = { { 0, 0, 0, 0, 0, 0, 0xF8, 0x7F } };
+#endif
+#if HAVE_DOUBLE_IEEE_LITTLE_SWAPPED
+static struct dbl_bytes dbl_infp = { { 0, 0, 0xF0, 0x7F, 0, 0, 0, 0 } };
+static struct dbl_bytes dbl_infm = { { 0, 0, 0xF0, 0xFF, 0, 0, 0, 0 } };
+static struct dbl_bytes dbl_nan = { { 0, 0, 0xF8, 0x7F, 0, 0, 0, 0 } };
+#endif
+#if HAVE_DOUBLE_IEEE_BIG_ENDIAN
+static struct dbl_bytes dbl_infp = { { 0x7F, 0xF0, 0, 0, 0, 0, 0, 0 } };
+static struct dbl_bytes dbl_infm = { { 0xFF, 0xF0, 0, 0, 0, 0, 0, 0 } };
+static struct dbl_bytes dbl_nan = { { 0x7F, 0xF8, 0, 0, 0, 0, 0, 0 } };
+#endif
+#endif
+
+
/* multiplies 1/2 <= d <= 1 by 2^exp */
static double
mpfr_scale2 (double d, int exp)
@@ -108,12 +140,24 @@ mpfr_get_d3 (mpfr_srcptr src, mp_exp_t e, mp_rnd_t rnd_mode)
int negative;
if (MPFR_IS_NAN(src))
- return MPFR_DBL_NAN;
+ {
+#ifdef MPFR_DBL_NAN
+ return MPFR_DBL_NAN;
+#else
+ DIVIDE_BY_ZERO;
+#endif
+ }
negative = MPFR_SIGN(src) < 0;
if (MPFR_IS_INF(src))
- return negative ? MPFR_DBL_INFM : MPFR_DBL_INFP;
+ {
+#ifdef MPFR_DBL_INFP
+ return negative ? MPFR_DBL_INFM : MPFR_DBL_INFP;
+#else
+ DIVIDE_BY_ZERO;
+#endif
+ }
if (MPFR_IS_ZERO(src))
return negative ? -0.0 : 0.0;