pxd: initial work
[pspp] / src / libpspp / float-format.h
index 047ae91e346ee78c7cd00faee90f7f5d4d61b158..028a4e8d0c7ad711ac3135285f2a798567d2f6bc 100644 (file)
@@ -1,30 +1,31 @@
-/* PSPP - computes sample statistics.
-   Copyright (C) 2006 Free Software Foundation, Inc.
+/* PSPP - a program for statistical analysis.
+   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 the Free Software Foundation; either version 2 of the
-   License, or (at your option) any later version.
+   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
+   the Free Software Foundation, either version 3 of the License, or
+   (at your option) any later version.
 
-   This program is distributed in the hope that it will be useful, but
-   WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   General Public License for more details.
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
 
    You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software
-   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
-   02110-1301, USA. */
+   along with this program.  If not, see <http://www.gnu.org/licenses/>. */
 
 #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 
+enum float_format
   {
     /* IEEE 754 formats. */
     FLOAT_IEEE_SINGLE_LE,          /* 32 bit, little endian. */
@@ -45,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,
@@ -56,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 *);
 
@@ -72,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 */