Fixed use of isfinite and _isfinite
authorMark Abraham <mark.j.abraham@gmail.com>
Wed, 4 Jan 2012 03:47:05 +0000 (14:47 +1100)
committerMark Abraham <mark.j.abraham@gmail.com>
Tue, 10 Jan 2012 14:06:35 +0000 (01:06 +1100)
Implemented proper CMake tests for the above functionality.
Catered for MSVC idiosyncratic _finite() function. Removed
erroneous use of HAS_ISFINITE and HAS__ISFINITE.
Encapsulated the use of preprocessor directives into the new
gmx_isfinite() function so the programmer doesn't need to
know about the foregoing mess.

The previous versions resulted in unreachable code.

Change-Id: I7471388ed8f402c3f8b664e7846465de4b85f578

CMakeLists.txt
cmake/gmxTestIsfinite.cmake [new file with mode: 0644]
include/maths.h
src/config.h.cmakein
src/gmxlib/maths.c
src/mdlib/clincs.c
src/tools/geminate.c

index b56aad1bb2e38a2a20dbb71aa3c479328da4b58d..85af2a8958698ddce3fe58c10ffafe095d71a719 100644 (file)
@@ -333,8 +333,6 @@ check_function_exists(_aligned_malloc   HAVE__ALIGNED_MALLOC)
 check_function_exists(gettimeofday      HAVE_GETTIMEOFDAY)
 check_function_exists(isnan             HAVE_ISNAN)
 check_function_exists(_isnan            HAVE__ISNAN)
-check_function_exists(isfinite          HAVE_ISFINITE)
-check_function_exists(_isfinite         HAVE__ISFINITE)
 check_function_exists(fsync             HAVE_FSYNC)
 check_function_exists(_fileno           HAVE__FILENO)
 check_function_exists(fileno            HAVE_FILENO)
@@ -532,6 +530,11 @@ gmx_test_inline(RESTRICT_KEYWORD)
 include(gmxTestPipes)
 gmx_test_pipes(HAVE_PIPES)
 
+include(gmxTestIsfinite)
+gmx_test_isfinite(HAVE_ISFINITE)
+gmx_test__isfinite(HAVE__ISFINITE)
+gmx_test__finite(HAVE__FINITE)
+
 include(gmxTestInlineASM)
 gmx_test_inline_asm_gcc_x86(GMX_X86_GCC_INLINE_ASM)
 gmx_test_inline_asm_msvc_x86(GMX_X86_MSVC_INLINE_ASM)
diff --git a/cmake/gmxTestIsfinite.cmake b/cmake/gmxTestIsfinite.cmake
new file mode 100644 (file)
index 0000000..95c07fe
--- /dev/null
@@ -0,0 +1,77 @@
+# - Define macro to check if isfinite or _isfinite exists
+#
+#  gmx_test_isfinite(VARIABLE)
+#
+#  VARIABLE will be set to true if isfinite exists
+#
+#  gmx_test__isfinite(VARIABLE)
+#
+#  VARIABLE will be set to true if _isfinite exists
+#
+#  gmx_test__finite(VARIABLE) - disabled since it doesn't seem to work the way the MSVC docs suggest
+#
+#  VARIABLE will be set to true if _finite exists
+#
+
+MACRO(gmx_test_isfinite VARIABLE)
+    MESSAGE(STATUS "Checking for isfinite")
+
+    set(CMAKE_REQUIRED_INCLUDES "math.h")
+    set(CMAKE_REQUIRED_LIBRARIES "m")
+    check_c_source_compiles(
+      "#include <math.h>
+int main(void) {
+  float f;
+  isfinite(f);
+}" isfinite_compile_ok)
+
+    if(isfinite_compile_ok)
+        MESSAGE(STATUS "Checking for isfinite - yes")
+            set(${VARIABLE} ${isfinite_compile_ok}
+                "Result of test for isfinite")
+    else(isfinite_compile_ok)
+        MESSAGE(STATUS "Checking for isfinite - no")
+    endif(isfinite_compile_ok)
+ENDMACRO(gmx_test_isfinite VARIABLE)
+
+MACRO(gmx_test__isfinite VARIABLE)
+    MESSAGE(STATUS "Checking for _isfinite")
+
+    set(CMAKE_REQUIRED_INCLUDES "math.h")
+    set(CMAKE_REQUIRED_LIBRARIES "m")
+    check_c_source_compiles(
+      "#include <math.h>
+int main(void) {
+  float f;
+  _isfinite(f);
+}" _isfinite_compile_ok)
+
+    if(_isfinite_compile_ok)
+        MESSAGE(STATUS "Checking for _isfinite - yes")
+            set(${VARIABLE} ${_isfinite_compile_ok}
+                "Result of test for _isfinite")
+    else(_isfinite_compile_ok)
+        MESSAGE(STATUS "Checking for _isfinite - no")
+    endif(_isfinite_compile_ok)
+ENDMACRO(gmx_test__isfinite VARIABLE)
+
+# Necessary for MSVC
+MACRO(gmx_test__finite VARIABLE)
+    MESSAGE(STATUS "Checking for _finite")
+
+    set(CMAKE_REQUIRED_INCLUDES "float.h")
+    check_c_source_compiles(
+      "#include <float.h>
+int main(void) {
+  float f;
+  _finite(f);
+}" _finite_compile_ok)
+
+    if(_finite_compile_ok)
+        MESSAGE(STATUS "Checking for _finite - yes")
+            set(${VARIABLE} ${_finite_compile_ok}
+                "Result of test for _finite")
+    else(_finite_compile_ok)
+        MESSAGE(STATUS "Checking for _finite - no")
+    endif(_finite_compile_ok)
+ENDMACRO(gmx_test__finite VARIABLE)
index 782e7688f10b6c7c03b5a8191840aea99f710365..ed7503205c0f96b1a07cb5fd53e43744d417dafe 100644 (file)
@@ -101,6 +101,8 @@ real    cuberoot (real a);
 real    gmx_erf(real x);
 real    gmx_erfc(real x);
 
+gmx_bool gmx_isfinite(real x);
+
 /*! \brief Check if two numbers are within a tolerance
  *
  *  This routine checks if the relative difference between two numbers is
index 89c9c8a567b5a86a856c90c6535a2a716c12503f..91873e6dccb8a7f521cc7fd1183b112f3ad9ae79 100644 (file)
 /* Define to 1 if you have the _isfinite() function. */
 #cmakedefine HAVE__ISFINITE
 
+/* Define to 1 if you have the _finite() function. */
+#cmakedefine HAVE__FINITE
+
 /* Define to 1 if you have the fsync() function. */
 #cmakedefine HAVE_FSYNC
 
index 9ffa832b35b55f1440b737a1aa94181ef4b7458d..cfa55f6953fdb281e809482ec348d5d207c64025 100644 (file)
@@ -40,6 +40,9 @@
 #include <math.h>
 #include <limits.h>
 #include "maths.h"
+#ifdef HAVE__FINITE
+#include "float.h"
+#endif
 
 int gmx_nint(real a)
 {   
@@ -659,3 +662,19 @@ float fast_float_erfc(float x)
                t*(-0.82215223+t*0.17087277)))))))));
        return ans;
 }
+
+gmx_bool gmx_isfinite(real x)
+{
+    gmx_bool returnval = TRUE;
+    /* If no suitable function was found, assume the value is
+     * finite. */
+
+#ifdef HAVE_ISFINITE
+    returnval = isfinite(x);
+#elif defined HAVE__ISFINITE
+    returnval = _isfinite(x);
+#elif defined HAVE__FINITE
+    returnval = _finite(x);
+#endif
+    return returnval;
+}
index 9fc87071449f4b7109c3f8371c28608b6b2e574e..89531f60a4fd7505e989fdc54bab5869a275f2c5 100644 (file)
@@ -1036,15 +1036,10 @@ static void lincs_warning(FILE *fplog,
             {
                 fprintf(fplog,"%s",buf);
             }
-            #ifdef HAS_ISFINITE
-            if (!isfinite(d1)) 
-                gmx_fatal(FARGS,"Bond length not finite.")
-            #else
-            #ifdef HAS__ISFINITE
-            if (!_isfinite(d1))        
-                gmx_fatal(FARGS,"Bond length not finite.")
-            #endif
-            #endif
+            if (!gmx_isfinite(d1))
+            {
+                gmx_fatal(FARGS,"Bond length not finite.");
+            }
 
             (*warncount)++;
         }
index 0d160cdb47be93b72ded4dfb278fedb8cef44a0b..20f2430335dda83ecf90b430f9de95b5043e73ff 100644 (file)
@@ -887,13 +887,7 @@ extern real fitGemRecomb(double *ct, double *time, double **ctFit,
        for(i=0; i<GD->nData; i++)
          {
            dumpdata[i] = (real)(GD->ctTheory[i]);
-#ifdef HAS_ISFINITE
-           if (!isfinite(dumpdata[i]))
-#elif defined HAS__ISFINITE
-           if (!_isfinite(dumpdata[i]))
-#else
-            if (0)
-#endif
+           if (!gmx_isfinite(dumpdata[i]))
              {
                gmx_fatal(FARGS, "Non-finite value in acf.");
              }