set(SOURCES libcompat.c)
+set(SOURCES fpclassify.c)
+
if (NOT HAVE_LIBRT)
set(SOURCES ${SOURCES} clock_gettime.c)
set(SOURCES ${SOURCES} timer_create.c)
--- /dev/null
+/* Replacement function for isnan/isinf/isfinite for processors using
+ * IEEE 754 floating point format.
+ * Copyright (C) 2017, bel2125
+ * License: LGPL v2 or MIT (as you like).
+ */
+
+
+#include "libcompat.h"
+
+#if !defined(isnan) || !defined(isinf) || !defined(isfinite)
+
+#if defined(HAVE_STDINT_H)
+#include <stdint.h>
+typedef uint64_t bitfield64;
+#elif defined(_MSC_VER)
+typedef unsigned __int64 bitfield64;
+#else
+typedef unsigned long long bitfield64;
+#endif
+
+static bitfield64 ms = 0x8000000000000000;
+static bitfield64 me = 0x7FF0000000000000;
+static bitfield64 mf = 0x000FFFFFFFFFFFFF;
+
+int fpclassify(double d)
+{
+ bitfield64 *p = (bitfield64 *)&d;
+ if ((*p & me) != me) {
+ /* finite */
+ if (*p & mf) {
+ /* finite and not null */
+ if (*p & me) {
+ return FP_NORMAL;
+ }
+ return FP_SUBNORMAL;
+ }
+ return FP_ZERO;
+ }
+ if (*p & mf) {
+ return FP_NAN;
+ }
+ return FP_INFINITE;
+}
+
+#endif
+
/* defines exit() */
#include <stdlib.h>
+/* defines NAN, INFINITY, isnan(), isinf(), isfinite() */
+#include <math.h>
+
+/* However, some older Visual Studio Versions do not */
+#if !defined(INFINITY)
+double ZERO = 0.0;
+double INFINITY = 1.0 / ZERO;
+#endif
+#if !defined(NAN)
+double NAN = INFINITY * ZERO;
+#endif
+#if !defined(isnan) || !defined(isinf) || !defined(isfinite)
+#define FP_INFINITE (1)
+#define FP_NAN (2)
+#define FP_ZERO (4)
+#define FP_NORMAL (8)
+#define FP_SUBNORMAL (16)
+#define isnan(x) ((fpclassify((double)(x)) & FP_NAN) == FP_NAN)
+#define isnan(x) ((fpclassify((double)(x)) & FP_INFINITE) == FP_INFINITE)
+#define isfinite(x) ((fpclassify((double)(x)) & (FP_NAN|FP_INFINITE)) == 0)
+#endif
+
+
/* provides localtime and struct tm */
#ifdef HAVE_SYS_TIME_H
#include <sys/time.h>
#include "../lib/libcompat.h"
-#include <math.h>
#include <sys/types.h>
#include <stdlib.h>
#include <signal.h>
#include <check.h>
#include "check_check.h"
-#if !defined(NAN)
-/* According to POSIX, NAN and INFINITY are defined in math.h, see
- * http://pubs.opengroup.org/onlinepubs/009695399/basedefs/math.h.html
- * Hovever, older Visual Studio compilers do not define these values.
- */
-double NAN;
-#endif
-#if !defined(INFINITY)
-double INFINITY;
-#endif
-#if !defined(isnan)
-int isnan(double d) {
-#ifdef _MSC_VER
- unsigned __int64 *p = &d, m = 0x7FF0000000000000;
-#else
- unsigned long long *p = &d, m = 0x7FF0000000000000;
-#endif
- if ((*p & m) != m) return 0; /* finite */
- *p &= 0x000FFFFFFFFFFFFF; /* mask exponent and sign */
- return *p != 0;
-}
-#endif
-#if !defined(isinf)
-int isinf(double d) {
-#ifdef _MSC_VER
- unsigned __int64 *p = &d, m = 0x7FF0000000000000;
-#else
- unsigned long long *p = &d, m = 0x7FF0000000000000;
-#endif
- *p &= 0x000FFFFFFFFFFFFF; /* mask exponent and sign */
- return *p == 0;
-}
-#endif
-#if !defined(isfinite)
-int isfinite(double d) {
-#ifdef _MSC_VER
- unsigned __int64 *p = &d, m = 0x7FF0000000000000;
-#else
- unsigned long long *p = &d, m = 0x7FF0000000000000;
-#endif
- return (*p & m) != m;
-}
-#endif
-
START_TEST(test_lno)
{
TCase *tc_exit_handlers;
#endif
-#if !defined(NAN)
- NAN /= NAN; /* division of 0 by 0 */
-#endif
-#if !defined(INFINITY)
- INFINITY = 1.0 / INFINITY; /* division of 1 by 0 */
-#endif
-
s = suite_create("Check Servant");
tc_simple = tcase_create("Simple Tests");