]> https://gitweb.dealii.org/ - dealii.git/commitdiff
check for std::isnan and make sure we never use a function that does not exist 1073/head
authorGuido Kanschat <dr.guido.kanschat@gmail.com>
Fri, 3 Jul 2015 10:09:45 +0000 (12:09 +0200)
committerGuido Kanschat <dr.guido.kanschat@gmail.com>
Fri, 3 Jul 2015 10:18:41 +0000 (12:18 +0200)
cmake/checks/check_01_cxx_features.cmake
include/deal.II/base/config.h.in
include/deal.II/base/numbers.h
include/deal.II/lac/vector.templates.h
source/base/config.cc
source/lac/solver_control.cc

index 1bb9f98169be9717beb73db38d0fed7b883b963e..46022e6857dd42377fa3b274f858812365e78d82 100644 (file)
@@ -393,6 +393,14 @@ IF(DEAL_II_HAVE_CXX11)
     DEAL_II_HAVE_CXX11_IS_TRIVIALLY_COPYABLE)
 ENDIF()
 
+CHECK_CXX_SOURCE_COMPILES(
+  "
+  #include <cmath>
+  int main(){ double d=0; std::isnan (d); return 0; }
+  "
+  DEAL_II_HAVE_STD_ISNAN)
+
+
 CHECK_CXX_SOURCE_COMPILES(
   "
   #include <cmath>
index a70d2deb991956657081f5676febd74cd88a59b3..d3b7a9696400bfb0ba8c30a94da5e690898b451a 100644 (file)
 
 #cmakedefine DEAL_II_HAVE_CXX11_IS_TRIVIALLY_COPYABLE
 #cmakedefine DEAL_II_HAVE_ISNAN
+#cmakedefine DEAL_II_HAVE_STD_ISNAN
 #cmakedefine DEAL_II_HAVE_UNDERSCORE_ISNAN
 #cmakedefine DEAL_II_HAVE_ISFINITE
 
index ae134e637a2b16a539c6f2a293b5e57c8b908c1f..699157fb7e9e0b367b1a3c6de8178faf1a6f173f 100644 (file)
@@ -90,6 +90,18 @@ namespace numbers
    */
   static const double  SQRT1_2 = 0.70710678118654752440;
 
+  /**
+   * Check whether a value is not a number.
+   *
+   * This function uses either <code>std::isnan</code>,
+   * <code>isnan</code>, or <code>_isnan</code>, whichever is
+   * available on the system and returns the result.
+   *
+   * If none of the functions detecting NaN is available, this
+   * function returns false.
+   */
+  bool is_nan (const double x);
+
   /**
    * Return @p true if the given value is a finite floating point number, i.e.
    * is neither plus or minus infinity nor NaN (not a number).
@@ -222,13 +234,68 @@ namespace numbers
     real_type abs (const std::complex<number> &x);
   };
 
-}
+  // --------------- inline and template functions ---------------- //
 
+  inline bool is_nan (const double x)
+  {
+#ifdef DEAL_II_HAVE_STD_ISNAN
+    return std::isnan(x);
+#elif defined(DEAL_II_HAVE_ISNAN)
+    return isnan(x);
+#elif defined(DEAL_II_HAVE_UNDERSCORE_ISNAN)
+    return _isnan(x);
+#else
+    return false;
+#endif
+  }
+
+  inline bool is_finite (const double x)
+  {
+#ifdef DEAL_II_HAVE_ISFINITE
+    return !is_nan(x) && std::isfinite (x);
+#else
+    // Check against infinities. Note
+    // that if x is a NaN, then both
+    // comparisons will be false
+    return ((x >= -std::numeric_limits<double>::max())
+            &&
+            (x <= std::numeric_limits<double>::max()));
+#endif
+  }
+
+
+
+  inline bool is_finite (const std::complex<double> &x)
+  {
+    // Check complex numbers for infinity
+    // by testing real and imaginary part
+    return ( is_finite (x.real())
+             &&
+             is_finite (x.imag()) );
+  }
+
+
+
+  inline bool is_finite (const std::complex<float> &x)
+  {
+    // Check complex numbers for infinity
+    // by testing real and imaginary part
+    return ( is_finite (x.real())
+             &&
+             is_finite (x.imag()) );
+  }
+
+
+
+  inline bool is_finite (const std::complex<long double> &x)
+  {
+    // Same for std::complex<long double>
+    return ( is_finite (x.real())
+             &&
+             is_finite (x.imag()) );
+  }
 
-// --------------- inline and template functions ---------------- //
 
-namespace numbers
-{
   template <typename number>
   const number &
   NumberTraits<number>::conjugate (const number &x)
index 45d39d3f4037e1a9bc549cee60e3e3abeacb179f..e80d2600b66553580f97446e0a050877717f7a9e 100644 (file)
@@ -1472,6 +1472,7 @@ Vector<Number>::lp_norm (const real_type p) const
 }
 
 
+
 template <>
 typename Vector<int>::real_type
 Vector<int>::lp_norm (const real_type) const
@@ -1481,6 +1482,7 @@ Vector<int>::lp_norm (const real_type) const
 }
 
 
+
 template <typename Number>
 typename Vector<Number>::real_type
 Vector<Number>::linfty_norm () const
index 265c04035cbb25340cc2617462ec00dcc020e708..983eef3023d45773b7cf9c0990c78a53c8642b2f 100644 (file)
@@ -22,53 +22,6 @@ DEAL_II_NAMESPACE_OPEN
 
 namespace numbers
 {
-  bool is_finite (const double x)
-  {
-#ifdef DEAL_II_HAVE_ISFINITE
-    return !std::isnan(x) && std::isfinite (x);
-#else
-    // Check against infinities. Note
-    // that if x is a NaN, then both
-    // comparisons will be false
-    return ((x >= -std::numeric_limits<double>::max())
-            &&
-            (x <= std::numeric_limits<double>::max()));
-#endif
-  }
-
-
-
-  bool is_finite (const std::complex<double> &x)
-  {
-    // Check complex numbers for infinity
-    // by testing real and imaginary part
-    return ( is_finite (x.real())
-             &&
-             is_finite (x.imag()) );
-  }
-
-
-
-  bool is_finite (const std::complex<float> &x)
-  {
-    // Check complex numbers for infinity
-    // by testing real and imaginary part
-    return ( is_finite (x.real())
-             &&
-             is_finite (x.imag()) );
-  }
-
-
-
-  bool is_finite (const std::complex<long double> &x)
-  {
-    // Same for std::complex<long double>
-    return ( is_finite (x.real())
-             &&
-             is_finite (x.imag()) );
-  }
-
-
   template <typename number>
   const bool NumberTraits<number>::is_complex;
 
index 9f1439fc69cca7b99708db1ade2e1a7b88f871b6..87acec4f1b9340c946aa98b95e74a69baa138d2c 100644 (file)
@@ -92,15 +92,7 @@ SolverControl::check (const unsigned int step,
     }
 
   if ((step >= maxsteps) ||
-#ifdef DEAL_II_HAVE_ISNAN
-      isnan(check_value) ||
-#else
-#  ifdef DEAL_II_HAVE_UNDERSCORE_ISNAN
-      // on Microsoft Windows, the
-      // function is called _isnan
-      _isnan(check_value) ||
-#  endif
-#endif
+      numbers::is_nan(check_value) ||
       (check_failure && (check_value > failure_residual))
      )
     {

In the beginning the Universe was created. This has made a lot of people very angry and has been widely regarded as a bad move.

Douglas Adams


Typeset in Trocchi and Trocchi Bold Sans Serif.