$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
Subject: [Boost-commit] svn:boost r74167 - in sandbox/big_number: boost/math/big_number boost/math/concepts libs/math/test
From: john_at_[hidden]
Date: 2011-08-30 14:08:57
Author: johnmaddock
Date: 2011-08-30 14:08:56 EDT (Tue, 30 Aug 2011)
New Revision: 74167
URL: http://svn.boost.org/trac/boost/changeset/74167
Log:
Added fpclassify routines.
Text files modified: 
   sandbox/big_number/boost/math/big_number/default_ops.hpp         |    67 ++++++++++++++++++++++++++++++++++++++++
   sandbox/big_number/boost/math/big_number/e_float.hpp             |     5 ++                                      
   sandbox/big_number/boost/math/big_number/mpfr.hpp                |     6 +++                                     
   sandbox/big_number/boost/math/concepts/big_number_architypes.hpp |     5 ++                                      
   sandbox/big_number/libs/math/test/test_numeric_limits.cpp        |    48 ++++++++++++++++++++++++++++            
   5 files changed, 130 insertions(+), 1 deletions(-)
Modified: sandbox/big_number/boost/math/big_number/default_ops.hpp
==============================================================================
--- sandbox/big_number/boost/math/big_number/default_ops.hpp	(original)
+++ sandbox/big_number/boost/math/big_number/default_ops.hpp	2011-08-30 14:08:56 EDT (Tue, 30 Aug 2011)
@@ -7,6 +7,7 @@
 #define BOOST_MATH_BIG_NUM_DEF_OPS
 
 #include <boost/math/big_number/big_number_base.hpp>
+#include <boost/math/special_functions/fpclassify.hpp>
 
 namespace boost{ namespace math{ namespace big_num_default_ops{
 
@@ -343,6 +344,11 @@
       result->negate();
 }
 
+template <class Backend>
+inline int eval_fpclassify(const Backend& arg)
+{
+   return is_zero(arg) ? FP_ZERO : FP_NORMAL;
+}
 //
 // These have to implemented by the backend, declared here so that our macro generated code compiles OK.
 //
@@ -376,6 +382,67 @@
 
 }
 
+//
+// Default versions of floating point classification routines:
+//
+template <class Backend>
+inline int fpclassify BOOST_PREVENT_MACRO_SUBSTITUTION(const big_number<Backend>& arg)
+{
+   using big_num_default_ops::eval_fpclassify;
+   return eval_fpclassify(arg.backend());
+}
+template <class Exp>
+inline int fpclassify BOOST_PREVENT_MACRO_SUBSTITUTION(const detail::big_number_exp<Exp>& arg)
+{
+   typedef typename expression_type<Exp>::type value_type;
+   return fpclassify(value_type(arg));
+}
+template <class Backend>
+inline bool isfinite BOOST_PREVENT_MACRO_SUBSTITUTION(const big_number<Backend>& arg)
+{
+   int v = fpclassify(arg);
+   return (v != FP_INFINITE) && (v != FP_NAN);
+}
+template <class Exp>
+inline bool isfinite BOOST_PREVENT_MACRO_SUBSTITUTION(const detail::big_number_exp<Exp>& arg)
+{
+   typedef typename expression_type<Exp>::type value_type;
+   return isfinite(value_type(arg));
+}
+template <class Backend>
+inline bool isnan BOOST_PREVENT_MACRO_SUBSTITUTION(const big_number<Backend>& arg)
+{
+   return fpclassify(arg) == FP_NAN;
+}
+template <class Exp>
+inline bool isnan BOOST_PREVENT_MACRO_SUBSTITUTION(const detail::big_number_exp<Exp>& arg)
+{
+   typedef typename expression_type<Exp>::type value_type;
+   return isnan(value_type(arg));
+}
+template <class Backend>
+inline bool isinf BOOST_PREVENT_MACRO_SUBSTITUTION(const big_number<Backend>& arg)
+{
+   return fpclassify(arg) == FP_INFINITE;
+}
+template <class Exp>
+inline bool isinf BOOST_PREVENT_MACRO_SUBSTITUTION(const detail::big_number_exp<Exp>& arg)
+{
+   typedef typename expression_type<Exp>::type value_type;
+   return isinf(value_type(arg));
+}
+template <class Backend>
+inline bool isnormal BOOST_PREVENT_MACRO_SUBSTITUTION(const big_number<Backend>& arg)
+{
+   return fpclassify(arg) == FP_NORMAL;
+}
+template <class Exp>
+inline bool isnormal BOOST_PREVENT_MACRO_SUBSTITUTION(const detail::big_number_exp<Exp>& arg)
+{
+   typedef typename expression_type<Exp>::type value_type;
+   return isnormal(value_type(arg));
+}
+
 #define UNARY_OP_FUNCTOR(func)\
 namespace detail{\
 template <class Backend>\
Modified: sandbox/big_number/boost/math/big_number/e_float.hpp
==============================================================================
--- sandbox/big_number/boost/math/big_number/e_float.hpp	(original)
+++ sandbox/big_number/boost/math/big_number/e_float.hpp	2011-08-30 14:08:56 EDT (Tue, 30 Aug 2011)
@@ -69,7 +69,10 @@
 {
    *result = val.data().extract_long_double();
 }
-
+inline int eval_fpclassify(const arithmetic_backend<efx::e_float>& val)
+{
+   return val.data().isinf() ? FP_INFINITE : val.data().isnan() ? FP_NAN : val.data().iszero() ? FP_ZERO : FP_NORMAL;
+}
 
 
 }} // namespaces
Modified: sandbox/big_number/boost/math/big_number/mpfr.hpp
==============================================================================
--- sandbox/big_number/boost/math/big_number/mpfr.hpp	(original)
+++ sandbox/big_number/boost/math/big_number/mpfr.hpp	2011-08-30 14:08:56 EDT (Tue, 30 Aug 2011)
@@ -642,6 +642,12 @@
    return ldexp(result, val, -*e);
 }
 
+template <unsigned Digits10>
+inline int eval_fpclassify(const mpfr_real_backend<Digits10>& val)
+{
+   return mpfr_inf_p(val.data()) ? FP_INFINITE : mpfr_nan_p(val.data()) ? FP_NAN : mpfr_zero_p(val.data()) ? FP_ZERO : FP_NORMAL;
+}
+
 typedef big_number<mpfr_real_backend<50> >    mpfr_real_50;
 typedef big_number<mpfr_real_backend<100> >   mpfr_real_100;
 typedef big_number<mpfr_real_backend<500> >   mpfr_real_500;
Modified: sandbox/big_number/boost/math/concepts/big_number_architypes.hpp
==============================================================================
--- sandbox/big_number/boost/math/concepts/big_number_architypes.hpp	(original)
+++ sandbox/big_number/boost/math/concepts/big_number_architypes.hpp	2011-08-30 14:08:56 EDT (Tue, 30 Aug 2011)
@@ -183,6 +183,11 @@
    result = std::fabs(arg.m_value);
 }
 
+inline int eval_fpclassify(const big_number_backend_real_architype& arg)
+{
+   return boost::math::fpclassify(arg.m_value);
+}
+
 typedef boost::math::big_number<big_number_backend_real_architype> big_number_real_architype;
 
 }}} // namespaces
Modified: sandbox/big_number/libs/math/test/test_numeric_limits.cpp
==============================================================================
--- sandbox/big_number/libs/math/test/test_numeric_limits.cpp	(original)
+++ sandbox/big_number/libs/math/test/test_numeric_limits.cpp	2011-08-30 14:08:56 EDT (Tue, 30 Aug 2011)
@@ -79,6 +79,54 @@
    PRINT(traps);
    PRINT(tinyness_before);
    PRINT(round_style);
+
+   if(std::numeric_limits<Number>::is_specialized)
+   {
+      if(std::numeric_limits<Number>::has_quiet_NaN)
+      {
+         BOOST_TEST((boost::math::isnan)(std::numeric_limits<Number>::quiet_NaN()));
+         BOOST_TEST(FP_NAN == (boost::math::fpclassify)(std::numeric_limits<Number>::quiet_NaN()));
+         BOOST_TEST(!(boost::math::isfinite)(std::numeric_limits<Number>::quiet_NaN()));
+         BOOST_TEST(!(boost::math::isnormal)(std::numeric_limits<Number>::quiet_NaN()));
+         BOOST_TEST(!(boost::math::isinf)(std::numeric_limits<Number>::quiet_NaN()));
+      }
+      if(std::numeric_limits<Number>::has_signaling_NaN)
+      {
+         BOOST_TEST((boost::math::isnan)(std::numeric_limits<Number>::signaling_NaN()));
+         BOOST_TEST(FP_NAN == (boost::math::fpclassify)(std::numeric_limits<Number>::signaling_NaN()));
+         BOOST_TEST(!(boost::math::isfinite)(std::numeric_limits<Number>::signaling_NaN()));
+         BOOST_TEST(!(boost::math::isnormal)(std::numeric_limits<Number>::signaling_NaN()));
+         BOOST_TEST(!(boost::math::isinf)(std::numeric_limits<Number>::signaling_NaN()));
+      }
+      if(std::numeric_limits<Number>::has_infinity)
+      {
+         BOOST_TEST((boost::math::isinf)(std::numeric_limits<Number>::infinity()));
+         BOOST_TEST(FP_INFINITE == (boost::math::fpclassify)(std::numeric_limits<Number>::infinity()));
+         BOOST_TEST(!(boost::math::isfinite)(std::numeric_limits<Number>::infinity()));
+         BOOST_TEST(!(boost::math::isnormal)(std::numeric_limits<Number>::infinity()));
+         BOOST_TEST(!(boost::math::isnan)(std::numeric_limits<Number>::infinity()));
+      }
+      if(std::numeric_limits<Number>::has_denorm)
+      {
+         BOOST_TEST(FP_SUBNORMAL == (boost::math::fpclassify)(std::numeric_limits<Number>::denorm_min()));
+         BOOST_TEST((boost::math::isfinite)(std::numeric_limits<Number>::denorm_min()));
+         BOOST_TEST(!(boost::math::isnormal)(std::numeric_limits<Number>::denorm_min()));
+         BOOST_TEST(!(boost::math::isinf)(std::numeric_limits<Number>::denorm_min()));
+         BOOST_TEST(!(boost::math::isnan)(std::numeric_limits<Number>::denorm_min()));
+      }
+   }
+   Number n = 0;
+   BOOST_TEST((boost::math::fpclassify)(n) == FP_ZERO);
+   BOOST_TEST((boost::math::isfinite)(n));
+   BOOST_TEST(!(boost::math::isnormal)(n));
+   BOOST_TEST(!(boost::math::isinf)(n));
+   BOOST_TEST(!(boost::math::isnan)(n));
+   n = 2;
+   BOOST_TEST((boost::math::fpclassify)(n) == FP_NORMAL);
+   BOOST_TEST((boost::math::isfinite)(n));
+   BOOST_TEST((boost::math::isnormal)(n));
+   BOOST_TEST(!(boost::math::isinf)(n));
+   BOOST_TEST(!(boost::math::isnan)(n));
 }