pxd: initial work
[pspp] / src / libpspp / float-format.h
index 5cf7a33a2faa35a764de745155ff2e3dc9733e92..028a4e8d0c7ad711ac3135285f2a798567d2f6bc 100644 (file)
@@ -1,5 +1,5 @@
 /* PSPP - a program for statistical analysis.
-   Copyright (C) 2006 Free Software Foundation, Inc.
+   Copyright (C) 2006, 2010-2012 Free Software Foundation, Inc.
 
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
 #ifndef LIBPSPP_FLOAT_FORMAT_H
 #define LIBPSPP_FLOAT_FORMAT_H 1
 
+#include <byteswap.h>
 #include <stdbool.h>
+#include <stdint.h>
+#include <string.h>
 #include <stddef.h>
-#include <libpspp/compiler.h>
+#include "libpspp/compiler.h"
 
 /* A floating-point format. */
 enum float_format
@@ -43,7 +46,6 @@ enum float_format
     FLOAT_FP,                      /* Neutral intermediate format. */
     FLOAT_HEX,                     /* C99 hexadecimal floating constant. */
 
-#ifdef FPREP_IEEE754
 #ifdef WORDS_BIGENDIAN
     FLOAT_NATIVE_FLOAT = FLOAT_IEEE_SINGLE_BE,
     FLOAT_NATIVE_DOUBLE = FLOAT_IEEE_DOUBLE_BE,
@@ -54,12 +56,12 @@ enum float_format
     FLOAT_NATIVE_DOUBLE = FLOAT_IEEE_DOUBLE_LE,
     FLOAT_NATIVE_32_BIT = FLOAT_IEEE_SINGLE_LE,
     FLOAT_NATIVE_64_BIT = FLOAT_IEEE_DOUBLE_LE
-#endif
-#else
-#error Only IEEE-754 floating point currently supported for PSPP hosts.
 #endif
   };
 
+static inline uint64_t double_to_ieee64le (double x);
+static inline double ieee64le_to_double (uint64_t x);
+
 void float_convert (enum float_format, const void *,
                     enum float_format, void *);
 
@@ -70,4 +72,40 @@ size_t float_get_size (enum float_format) PURE_FUNCTION;
 int float_identify (double expected_value, const void *, size_t,
                     enum float_format *best_guess);
 
+double float_get_lowest (void);
+\f
+static inline uint64_t
+double_to_ieee64le (double x)
+{
+  uint64_t y;
+
+#if FLOAT_NATIVE_DOUBLE == FLOAT_IEEE_DOUBLE_LE
+  memcpy (&y, &x, sizeof y);
+#elif FLOAT_NATIVE_DOUBLE == FLOAT_IEEE_DOUBLE_BE
+  memcpy (&y, &x, sizeof y);
+  y = bswap_64 (y);
+#else
+  float_convert (&x, FLOAT_NATIVE_DOUBLE, &y, FLOAT_IEEE_DOUBLE_LE);
+#endif
+
+  return y;
+}
+
+static inline double
+ieee64le_to_double (uint64_t x)
+{
+  double y;
+
+#if FLOAT_NATIVE_DOUBLE == FLOAT_IEEE_DOUBLE_LE
+  memcpy (&y, &x, sizeof y);
+#elif FLOAT_NATIVE_DOUBLE == FLOAT_IEEE_DOUBLE_BE
+  x = bswap_64 (x);
+  memcpy (&y, &x, sizeof y);
+#else
+  float_convert (&x, FLOAT_IEEE_DOUBLE_LE, &y, FLOAT_NATIVE_DOUBLE);
+#endif
+
+  return y;
+}
+
 #endif /* float-format.h */