Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r75452 - in sandbox/big_number: boost/multiprecision boost/multiprecision/detail boost/multiprecision/detail/functions libs/multiprecision/test
From: john_at_[hidden]
Date: 2011-11-12 07:15:06


Author: johnmaddock
Date: 2011-11-12 07:15:04 EST (Sat, 12 Nov 2011)
New Revision: 75452
URL: http://svn.boost.org/trac/boost/changeset/75452

Log:
Fixes for bugs in mp_float.
Fix constant initialization.
Add some instrumentation code.
Make mp_exp constructor explicit.
Remove some dead code.
Note mp_float division has outstanding bugs still!!
Added:
   sandbox/big_number/libs/multiprecision/test/test_fpclassify.cpp (contents, props changed)
Text files modified:
   sandbox/big_number/boost/multiprecision/detail/default_ops.hpp | 10 ++++++++
   sandbox/big_number/boost/multiprecision/detail/functions/constants.hpp | 12 ++++++++++
   sandbox/big_number/boost/multiprecision/detail/functions/pow.hpp | 6 ++++
   sandbox/big_number/boost/multiprecision/detail/mp_number_base.hpp | 22 +++++++++---------
   sandbox/big_number/boost/multiprecision/mp_float.hpp | 24 +++++++++++++------
   sandbox/big_number/boost/multiprecision/mpfr.hpp | 1
   sandbox/big_number/libs/multiprecision/test/Jamfile.v2 | 47 +++++++++++++++++++++++++++++++++------
   sandbox/big_number/libs/multiprecision/test/test_round.cpp | 1
   8 files changed, 93 insertions(+), 30 deletions(-)

Modified: sandbox/big_number/boost/multiprecision/detail/default_ops.hpp
==============================================================================
--- sandbox/big_number/boost/multiprecision/detail/default_ops.hpp (original)
+++ sandbox/big_number/boost/multiprecision/detail/default_ops.hpp 2011-11-12 07:15:04 EST (Sat, 12 Nov 2011)
@@ -14,6 +14,16 @@
 #include <boost/mpl/front.hpp>
 #include <boost/cstdint.hpp>
 
+#ifndef INSTRUMENT_BACKEND
+#ifndef BOOST_MP_INSTRUMENT
+#define INSTRUMENT_BACKEND(x)
+#else
+#define INSTRUMENT_BACKEND(x)\
+ std::cout << BOOST_STRINGIZE(x) << " = " << x.str(0, true) << std::endl;
+#endif
+#endif
+
+
 namespace boost{ namespace multiprecision{ namespace default_ops{
 
 //

Modified: sandbox/big_number/boost/multiprecision/detail/functions/constants.hpp
==============================================================================
--- sandbox/big_number/boost/multiprecision/detail/functions/constants.hpp (original)
+++ sandbox/big_number/boost/multiprecision/detail/functions/constants.hpp 2011-11-12 07:15:04 EST (Sat, 12 Nov 2011)
@@ -40,7 +40,10 @@
    }
    multiply(denom, ui_type(4));
    multiply(num, ui_type(3));
+ INSTRUMENT_BACKEND(denom);
+ INSTRUMENT_BACKEND(num);
    divide(num, denom);
+ INSTRUMENT_BACKEND(num);
 }
 
 template <class T>
@@ -142,7 +145,10 @@
    static T result;
    static bool b = false;
    if(!b)
+ {
       calc_log2(result, std::numeric_limits<mp_number<T> >::digits);
+ b = true;
+ }
 
    constant_initializer<T, &get_constant_ln2<T> >::do_nothing();
 
@@ -155,7 +161,10 @@
    static T result;
    static bool b = false;
    if(!b)
+ {
       calc_e(result, std::numeric_limits<mp_number<T> >::digits);
+ b = true;
+ }
 
    constant_initializer<T, &get_constant_e<T> >::do_nothing();
 
@@ -168,7 +177,10 @@
    static T result;
    static bool b = false;
    if(!b)
+ {
       calc_pi(result, std::numeric_limits<mp_number<T> >::digits);
+ b = true;
+ }
 
    constant_initializer<T, &get_constant_pi<T> >::do_nothing();
 

Modified: sandbox/big_number/boost/multiprecision/detail/functions/pow.hpp
==============================================================================
--- sandbox/big_number/boost/multiprecision/detail/functions/pow.hpp (original)
+++ sandbox/big_number/boost/multiprecision/detail/functions/pow.hpp 2011-11-12 07:15:04 EST (Sat, 12 Nov 2011)
@@ -227,7 +227,7 @@
       xx.negate();
 
    // Check the range of the argument.
- static const canonical_exp_type maximum_arg_for_exp = std::numeric_limits<mp_number<T> >::max_exponent == 0 ? std::numeric_limits<long>::max() : std::numeric_limits<mp_number<T> >::max_exponent;
+ static const canonical_exp_type maximum_arg_for_exp = std::numeric_limits<mp_number<T> >::max_exponent == 0 ? (std::numeric_limits<long>::max)() : std::numeric_limits<mp_number<T> >::max_exponent;
 
    if(xx.compare(maximum_arg_for_exp) >= 0)
    {
@@ -356,6 +356,7 @@
    }
    
    multiply(result, get_constant_ln2<T>(), canonical_exp_type(e));
+ INSTRUMENT_BACKEND(result);
    subtract(t, ui_type(1)); /* -0.3 <= t <= 0.3 */
    if(!alternate)
       t.negate(); /* 0 <= t <= 0.33333 */
@@ -371,6 +372,7 @@
    multiply(lim, result, std::numeric_limits<mp_number<T> >::epsilon().backend());
    if(get_sign(lim) < 0)
       lim.negate();
+ INSTRUMENT_BACKEND(lim);
 
    ui_type k = 1;
    do
@@ -378,10 +380,12 @@
       ++k;
       multiply(pow, t);
       divide(t2, pow, k);
+ INSTRUMENT_BACKEND(t2);
       if(alternate && ((k & 1) != 0))
          add(result, t2);
       else
          subtract(result, t2);
+ INSTRUMENT_BACKEND(result);
    }while(lim.compare(t2) < 0);
 }
 

Modified: sandbox/big_number/boost/multiprecision/detail/mp_number_base.hpp
==============================================================================
--- sandbox/big_number/boost/multiprecision/detail/mp_number_base.hpp (original)
+++ sandbox/big_number/boost/multiprecision/detail/mp_number_base.hpp 2011-11-12 07:15:04 EST (Sat, 12 Nov 2011)
@@ -220,7 +220,7 @@
 
    mp_exp(const Arg1& a) : arg(a) {}
 
- left_type left()const { return arg; }
+ left_type left()const { return left_type(arg); }
 
    const Arg1& left_ref()const{ return arg; }
 
@@ -243,7 +243,7 @@
    typedef Arg1 result_type;
    typedef terminal tag_type;
 
- mp_exp(const Arg1& a) : arg(a) {}
+ explicit mp_exp(const Arg1& a) : arg(a) {}
 
    const Arg1& value()const { return arg; }
 
@@ -271,8 +271,8 @@
 
    mp_exp(const Arg1& a1, const Arg2& a2) : arg1(a1), arg2(a2) {}
 
- left_type left()const { return arg1; }
- right_type right()const { return arg2; }
+ left_type left()const { return left_type(arg1); }
+ right_type right()const { return right_type(arg2); }
    const Arg1& left_ref()const{ return arg1; }
    const Arg2& right_ref()const{ return arg2; }
 
@@ -308,9 +308,9 @@
 
    mp_exp(const Arg1& a1, const Arg2& a2, const Arg3& a3) : arg1(a1), arg2(a2), arg3(a3) {}
 
- left_type left()const { return arg1; }
- middle_type middle()const { return arg2; }
- right_type right()const { return arg3; }
+ left_type left()const { return left_type(arg1); }
+ middle_type middle()const { return middle_type(arg2); }
+ right_type right()const { return right_type(arg3); }
    const Arg1& left_ref()const{ return arg1; }
    const Arg2& middle_ref()const{ return arg2; }
    const Arg3& right_ref()const{ return arg3; }
@@ -343,13 +343,13 @@
 template <class tag, class Arg1, class Arg2, class Arg3>
 inline const detail::mp_exp<tag, Arg1, Arg2, Arg3>& operator + (const detail::mp_exp<tag, Arg1, Arg2, Arg3>& v) { return v; }
 template <class B>
-inline detail::mp_exp<detail::negate, mp_number<B> > operator - (const mp_number<B>& v) { return v; }
+inline detail::mp_exp<detail::negate, mp_number<B> > operator - (const mp_number<B>& v) { return detail::mp_exp<detail::negate, mp_number<B> >(v); }
 template <class tag, class Arg1, class Arg2, class Arg3>
-inline detail::mp_exp<detail::negate, detail::mp_exp<tag, Arg1, Arg2, Arg3> > operator - (const detail::mp_exp<tag, Arg1, Arg2, Arg3>& v) { return v; }
+inline detail::mp_exp<detail::negate, detail::mp_exp<tag, Arg1, Arg2, Arg3> > operator - (const detail::mp_exp<tag, Arg1, Arg2, Arg3>& v) { return detail::mp_exp<detail::negate, detail::mp_exp<tag, Arg1, Arg2, Arg3> >(v); }
 template <class B>
-inline detail::mp_exp<detail::complement_immediates, mp_number<B> > operator ~ (const mp_number<B>& v) { return v; }
+inline detail::mp_exp<detail::complement_immediates, mp_number<B> > operator ~ (const mp_number<B>& v) { return detail::mp_exp<detail::complement_immediates, mp_number<B> >(v); }
 template <class tag, class Arg1, class Arg2, class Arg3>
-inline detail::mp_exp<detail::bitwise_complement, detail::mp_exp<tag, Arg1, Arg2, Arg3> > operator ~ (const detail::mp_exp<tag, Arg1, Arg2, Arg3>& v) { return v; }
+inline detail::mp_exp<detail::bitwise_complement, detail::mp_exp<tag, Arg1, Arg2, Arg3> > operator ~ (const detail::mp_exp<tag, Arg1, Arg2, Arg3>& v) { return detail::mp_exp<detail::bitwise_complement, detail::mp_exp<tag, Arg1, Arg2, Arg3> >(v); }
 //
 // Then addition:
 //

Modified: sandbox/big_number/boost/multiprecision/mp_float.hpp
==============================================================================
--- sandbox/big_number/boost/multiprecision/mp_float.hpp (original)
+++ sandbox/big_number/boost/multiprecision/mp_float.hpp 2011-11-12 07:15:04 EST (Sat, 12 Nov 2011)
@@ -194,7 +194,7 @@
       init.do_nothing();
       static bool init = false;
       static const std::string str_max = std::string("9." + std::string(static_cast<std::size_t>(mp_float_max_digits10), static_cast<char>('9')))
- + std::string("e+" + boost::lexical_cast<std::string>(mp_float_max_exp));
+ + std::string("e+" + boost::lexical_cast<std::string>(mp_float_max_exp10));
       static mp_float val_max;
       if(!init)
       {
@@ -212,7 +212,7 @@
       if(!init)
       {
          init = true;
- val_min = std::string("1.0e" + boost::lexical_cast<std::string>(mp_float_min_exp)).c_str();
+ val_min = std::string("1.0e" + boost::lexical_cast<std::string>(mp_float_min_exp10)).c_str();
       }
       return val_min;
    }
@@ -285,7 +285,7 @@
    static const mp_float& eps()
    {
       init.do_nothing();
- static mp_float val(1.0, 1 - Digits10);
+ static mp_float val(1.0, 1 - (int)Digits10);
       return val;
    }
 
@@ -857,6 +857,14 @@
    }
    else
    {
+ if(iszero())
+ {
+ if(v.isnan() || v.iszero())
+ {
+ return *this = v;
+ }
+ return *this;
+ }
       mp_float t(v);
       t.calculate_inv();
       return operator*=(t);
@@ -1098,7 +1106,7 @@
    // is used. During the iterative steps, the precision of the calculation is limited
    // to the minimum required in order to minimize the run-time.
 
- static const boost::int32_t double_digits10_minus_one = static_cast<boost::int32_t>(static_cast<boost::int32_t>(Digits10) - static_cast<boost::int32_t>(1));
+ static const boost::int32_t double_digits10_minus_one = std::numeric_limits<double>::digits10 - 1;
 
    for(boost::uint32_t digits = double_digits10_minus_one; digits <= Digits10; digits *= static_cast<boost::int32_t>(2))
    {
@@ -1908,7 +1916,7 @@
    }
 
    // Check for overflow...
- if(exp > mp_float_max_exp)
+ if(exp > mp_float_max_exp10)
    {
       const bool b_result_is_neg = neg;
 
@@ -1918,9 +1926,9 @@
    }
 
    // ...and check for underflow.
- if(exp <= mp_float_min_exp)
+ if(exp <= mp_float_min_exp10)
    {
- if(exp == mp_float_min_exp)
+ if(exp == mp_float_min_exp10)
       {
          // Check for identity with the minimum value.
          mp_float<Digits10> test = *this;
@@ -2661,7 +2669,7 @@
       static const bool is_bounded = true;
       static const bool is_modulo = false;
       static const bool is_iec559 = false;
- static const int digits = boost::multiprecision::mp_float<Digits10>::mp_float_digits;
+ static const int digits = static_cast<int>(((Digits10 + 1) * 1000L) / 301L);
       static const int digits10 = boost::multiprecision::mp_float<Digits10>::mp_float_digits10;
       static const int max_digits10 = boost::multiprecision::mp_float<Digits10>::mp_float_max_digits10;
       static const boost::int64_t min_exponent = boost::multiprecision::mp_float<Digits10>::mp_float_min_exp; // Type differs from int.

Modified: sandbox/big_number/boost/multiprecision/mpfr.hpp
==============================================================================
--- sandbox/big_number/boost/multiprecision/mpfr.hpp (original)
+++ sandbox/big_number/boost/multiprecision/mpfr.hpp 2011-11-12 07:15:04 EST (Sat, 12 Nov 2011)
@@ -785,7 +785,6 @@
 template <unsigned Digits10>
 inline void eval_trunc(mpfr_float_backend<Digits10>& result, const mpfr_float_backend<Digits10>& val)
 {
- int c = eval_fpclassify(val);
    if(0 == mpfr_number_p(val.data()))
    {
       result = boost::math::policies::raise_rounding_error("boost::multiprecision::trunc<%1%>(%1%)", 0, mp_number<mpfr_float_backend<Digits10> >(val), 0, boost::math::policies::policy<>()).backend();

Modified: sandbox/big_number/libs/multiprecision/test/Jamfile.v2
==============================================================================
--- sandbox/big_number/libs/multiprecision/test/Jamfile.v2 (original)
+++ sandbox/big_number/libs/multiprecision/test/Jamfile.v2 2011-11-12 07:15:04 EST (Sat, 12 Nov 2011)
@@ -156,7 +156,7 @@
         : # requirements
               <define>TEST_MPFR_50
          [ check-target-builds ../config//has_mpfr : : <build>no ]
- : big_number_concept_check_mpfr_50 ;
+ : mp_number_concept_check_mpfr_50 ;
 
 run mp_number_concept_check.cpp mpfr
         : # command line
@@ -164,7 +164,7 @@
         : # requirements
               <define>TEST_MPFR_6
          [ check-target-builds ../config//has_mpfr : : <build>no ]
- : big_number_concept_check_mpfr_6 ;
+ : mp_number_concept_check_mpfr_6 ;
 
 run mp_number_concept_check.cpp mpfr
         : # command line
@@ -172,7 +172,7 @@
         : # requirements
               <define>TEST_MPFR_15
          [ check-target-builds ../config//has_mpfr : : <build>no ]
- : big_number_concept_check_mpfr_15 ;
+ : mp_number_concept_check_mpfr_15 ;
 
 run mp_number_concept_check.cpp mpfr
         : # command line
@@ -180,7 +180,7 @@
         : # requirements
               <define>TEST_MPFR_17
          [ check-target-builds ../config//has_mpfr : : <build>no ]
- : big_number_concept_check_mpfr_17 ;
+ : mp_number_concept_check_mpfr_17 ;
 
 run mp_number_concept_check.cpp mpfr
         : # command line
@@ -188,7 +188,7 @@
         : # requirements
               <define>TEST_MPFR_30
          [ check-target-builds ../config//has_mpfr : : <build>no ]
- : big_number_concept_check_mpfr_30 ;
+ : mp_number_concept_check_mpfr_30 ;
 
 run mp_number_concept_check.cpp gmp
         : # command line
@@ -196,21 +196,21 @@
         : # requirements
               <define>TEST_MPF_50
          [ check-target-builds ../config//has_gmp : : <build>no ]
- : big_number_concept_check_mpf50 ;
+ : mp_number_concept_check_mpf50 ;
 
 run mp_number_concept_check.cpp
         : # command line
         : # input files
         : # requirements
               <define>TEST_MP_FLOAT
- : big_number_concept_check_mp_float ;
+ : mp_number_concept_check_mp_float ;
 
 run mp_number_concept_check.cpp
         : # command line
         : # input files
         : # requirements
               <define>TEST_BACKEND
- : big_number_concept_check_backend_concept ;
+ : mp_number_concept_check_backend_concept ;
 
 run test_exp.cpp gmp
         : # command line
@@ -522,3 +522,34 @@
          [ check-target-builds ../config//has_mpfr : : <build>no ]
         : test_round_mp_float ;
 
+run test_fpclassify.cpp
+ : # command line
+ : # input files
+ : # requirements
+ <define>TEST_BACKEND
+ : test_fpclassify_backend_concept ;
+
+run test_fpclassify.cpp gmp
+ : # command line
+ : # input files
+ : # requirements
+ <define>TEST_MPF_50
+ [ check-target-builds ../config//has_gmp : : <build>no ]
+ : test_fpclassify_mpf50 ;
+
+run test_fpclassify.cpp mpfr
+ : # command line
+ : # input files
+ : # requirements
+ <define>TEST_MPFR_50
+ [ check-target-builds ../config//has_mpfr : : <build>no ]
+ : test_fpclassify_mpfr_50 ;
+
+run test_fpclassify.cpp
+ : # command line
+ : # input files
+ : # requirements
+ <define>TEST_MP_FLOAT
+ [ check-target-builds ../config//has_mpfr : : <build>no ]
+ : test_fpclassify_mp_float ;
+

Added: sandbox/big_number/libs/multiprecision/test/test_fpclassify.cpp
==============================================================================
--- (empty file)
+++ sandbox/big_number/libs/multiprecision/test/test_fpclassify.cpp 2011-11-12 07:15:04 EST (Sat, 12 Nov 2011)
@@ -0,0 +1,324 @@
+// Copyright John Maddock 2006.
+// Copyright Paul A. Bristow 2007
+// Use, modification and distribution are subject to the
+// Boost Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include <cmath>
+#include <math.h>
+#include <boost/limits.hpp>
+#include <boost/math/special_functions/fpclassify.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+#if !defined(TEST_MPF_50) && !defined(TEST_MPF) && !defined(TEST_BACKEND) && !defined(TEST_MPZ) && !defined(TEST_MP_FLOAT) && !defined(TEST_MPFR) && !defined(TEST_MPFR_50) && !defined(TEST_MPQ)
+# define TEST_MPF_50
+# define TEST_MPFR_50
+# define TEST_BACKEND
+# define TEST_MP_FLOAT
+
+#ifdef _MSC_VER
+#pragma message("CAUTION!!: No backend type specified so testing everything.... this will take some time!!")
+#endif
+#ifdef __GNUC__
+#pragma warning "CAUTION!!: No backend type specified so testing everything.... this will take some time!!"
+#endif
+
+#endif
+
+#if defined(TEST_MPF_50)
+#include <boost/multiprecision/gmp.hpp>
+#endif
+#ifdef TEST_MPFR_50
+#include <boost/multiprecision/mpfr.hpp>
+#endif
+#ifdef TEST_BACKEND
+#include <boost/multiprecision/concepts/mp_number_architypes.hpp>
+#endif
+#ifdef TEST_MP_FLOAT
+#include <boost/multiprecision/mp_float.hpp>
+#endif
+
+#ifdef _MSC_VER
+#pragma warning(disable: 4127) // conditional expression is constant
+#endif
+
+#define BOOST_CHECK_EQUAL(x, y)\
+ if(x != y)\
+ {\
+ BOOST_ERROR("Values were not equal.");\
+ BOOST_LIGHTWEIGHT_TEST_OSTREAM << x << " != " << y << std::endl;\
+ }
+
+const char* method_name(const boost::math::detail::native_tag&)
+{
+ return "Native";
+}
+
+const char* method_name(const boost::math::detail::generic_tag<true>&)
+{
+ return "Generic (with numeric limits)";
+}
+
+const char* method_name(const boost::math::detail::generic_tag<false>&)
+{
+ return "Generic (without numeric limits)";
+}
+
+const char* method_name(const boost::math::detail::ieee_tag&)
+{
+ return "IEEE std";
+}
+
+const char* method_name(const boost::math::detail::ieee_copy_all_bits_tag&)
+{
+ return "IEEE std, copy all bits";
+}
+
+const char* method_name(const boost::math::detail::ieee_copy_leading_bits_tag&)
+{
+ return "IEEE std, copy leading bits";
+}
+
+template <class T>
+void test()
+{
+ typedef typename boost::math::detail::fp_traits<T>::type traits;
+ typedef typename traits::method method;
+
+ T t = 2;
+ T u = 2;
+ BOOST_CHECK_EQUAL((::boost::math::fpclassify)(t), (int)FP_NORMAL);
+ BOOST_CHECK_EQUAL((::boost::math::fpclassify)(-t), (int)FP_NORMAL);
+ BOOST_CHECK_EQUAL((::boost::math::isfinite)(t), true);
+ BOOST_CHECK_EQUAL((::boost::math::isfinite)(-t), true);
+ BOOST_CHECK_EQUAL((::boost::math::isinf)(t), false);
+ BOOST_CHECK_EQUAL((::boost::math::isinf)(-t), false);
+ BOOST_CHECK_EQUAL((::boost::math::isnan)(t), false);
+ BOOST_CHECK_EQUAL((::boost::math::isnan)(-t), false);
+ BOOST_CHECK_EQUAL((::boost::math::isnormal)(t), true);
+ BOOST_CHECK_EQUAL((::boost::math::isnormal)(-t), true);
+ BOOST_CHECK_EQUAL((::boost::math::fpclassify)(t), (::boost::math::fpclassify)(t + 0));
+ if(std::numeric_limits<T>::is_specialized)
+ {
+ t = (std::numeric_limits<T>::max)();
+ BOOST_CHECK_EQUAL((::boost::math::fpclassify)(t), (int)FP_NORMAL);
+ BOOST_CHECK_EQUAL((::boost::math::fpclassify)(-t), (int)FP_NORMAL);
+ BOOST_CHECK_EQUAL((::boost::math::isfinite)(t), true);
+ BOOST_CHECK_EQUAL((::boost::math::isfinite)(-t), true);
+ BOOST_CHECK_EQUAL((::boost::math::isinf)(t), false);
+ BOOST_CHECK_EQUAL((::boost::math::isinf)(-t), false);
+ BOOST_CHECK_EQUAL((::boost::math::isnan)(t), false);
+ BOOST_CHECK_EQUAL((::boost::math::isnan)(-t), false);
+ BOOST_CHECK_EQUAL((::boost::math::isnormal)(t), true);
+ BOOST_CHECK_EQUAL((::boost::math::isnormal)(-t), true);
+ BOOST_CHECK_EQUAL((::boost::math::fpclassify)(t), (::boost::math::fpclassify)(t + 0));
+ t = (std::numeric_limits<T>::min)();
+ BOOST_CHECK_EQUAL((::boost::math::fpclassify)(t), (int)FP_NORMAL);
+ BOOST_CHECK_EQUAL((::boost::math::fpclassify)(-t), (int)FP_NORMAL);
+ BOOST_CHECK_EQUAL((::boost::math::isfinite)(t), true);
+ BOOST_CHECK_EQUAL((::boost::math::isfinite)(-t), true);
+ BOOST_CHECK_EQUAL((::boost::math::isinf)(t), false);
+ BOOST_CHECK_EQUAL((::boost::math::isinf)(-t), false);
+ BOOST_CHECK_EQUAL((::boost::math::isnan)(t), false);
+ BOOST_CHECK_EQUAL((::boost::math::isnan)(-t), false);
+ BOOST_CHECK_EQUAL((::boost::math::isnormal)(t), true);
+ BOOST_CHECK_EQUAL((::boost::math::isnormal)(-t), true);
+ BOOST_CHECK_EQUAL((::boost::math::fpclassify)(t), (::boost::math::fpclassify)(t + 0));
+ }
+ if(std::numeric_limits<T>::has_denorm)
+ {
+ t = (std::numeric_limits<T>::min)();
+ t /= 2;
+ if(t != 0)
+ {
+ BOOST_CHECK_EQUAL((::boost::math::fpclassify)(t), (int)FP_SUBNORMAL);
+ BOOST_CHECK_EQUAL((::boost::math::fpclassify)(-t), (int)FP_SUBNORMAL);
+ BOOST_CHECK_EQUAL((::boost::math::isfinite)(t), true);
+ BOOST_CHECK_EQUAL((::boost::math::isfinite)(-t), true);
+ BOOST_CHECK_EQUAL((::boost::math::isinf)(t), false);
+ BOOST_CHECK_EQUAL((::boost::math::isinf)(-t), false);
+ BOOST_CHECK_EQUAL((::boost::math::isnan)(t), false);
+ BOOST_CHECK_EQUAL((::boost::math::isnan)(-t), false);
+ BOOST_CHECK_EQUAL((::boost::math::isnormal)(t), false);
+ BOOST_CHECK_EQUAL((::boost::math::isnormal)(-t), false);
+ BOOST_CHECK_EQUAL((::boost::math::fpclassify)(t), (::boost::math::fpclassify)(t + 0));
+ }
+ t = std::numeric_limits<T>::denorm_min();
+ if((t != 0) && (t < (std::numeric_limits<T>::min)()))
+ {
+ BOOST_CHECK_EQUAL((::boost::math::fpclassify)(t), (int)FP_SUBNORMAL);
+ BOOST_CHECK_EQUAL((::boost::math::fpclassify)(-t), (int)FP_SUBNORMAL);
+ BOOST_CHECK_EQUAL((::boost::math::isfinite)(t), true);
+ BOOST_CHECK_EQUAL((::boost::math::isfinite)(-t), true);
+ BOOST_CHECK_EQUAL((::boost::math::isinf)(t), false);
+ BOOST_CHECK_EQUAL((::boost::math::isinf)(-t), false);
+ BOOST_CHECK_EQUAL((::boost::math::isnan)(t), false);
+ BOOST_CHECK_EQUAL((::boost::math::isnan)(-t), false);
+ BOOST_CHECK_EQUAL((::boost::math::isnormal)(t), false);
+ BOOST_CHECK_EQUAL((::boost::math::isnormal)(-t), false);
+ BOOST_CHECK_EQUAL((::boost::math::fpclassify)(t), (::boost::math::fpclassify)(t + 0));
+ }
+ }
+ else
+ {
+ std::cout << "Denormalised forms not tested" << std::endl;
+ }
+ t = 0;
+ BOOST_CHECK_EQUAL((::boost::math::fpclassify)(t), (int)FP_ZERO);
+ BOOST_CHECK_EQUAL((::boost::math::fpclassify)(-t), (int)FP_ZERO);
+ BOOST_CHECK_EQUAL((::boost::math::isfinite)(t), true);
+ BOOST_CHECK_EQUAL((::boost::math::isfinite)(-t), true);
+ BOOST_CHECK_EQUAL((::boost::math::isinf)(t), false);
+ BOOST_CHECK_EQUAL((::boost::math::isinf)(-t), false);
+ BOOST_CHECK_EQUAL((::boost::math::isnan)(t), false);
+ BOOST_CHECK_EQUAL((::boost::math::isnan)(-t), false);
+ BOOST_CHECK_EQUAL((::boost::math::isnormal)(t), false);
+ BOOST_CHECK_EQUAL((::boost::math::isnormal)(-t), false);
+ BOOST_CHECK_EQUAL((::boost::math::fpclassify)(t), (::boost::math::fpclassify)(t + 0));
+ t /= -u; // create minus zero if it exists
+ BOOST_CHECK_EQUAL((::boost::math::fpclassify)(t), (int)FP_ZERO);
+ BOOST_CHECK_EQUAL((::boost::math::fpclassify)(-t), (int)FP_ZERO);
+ BOOST_CHECK_EQUAL((::boost::math::isfinite)(t), true);
+ BOOST_CHECK_EQUAL((::boost::math::isfinite)(-t), true);
+ BOOST_CHECK_EQUAL((::boost::math::isinf)(t), false);
+ BOOST_CHECK_EQUAL((::boost::math::isinf)(-t), false);
+ BOOST_CHECK_EQUAL((::boost::math::isnan)(t), false);
+ BOOST_CHECK_EQUAL((::boost::math::isnan)(-t), false);
+ BOOST_CHECK_EQUAL((::boost::math::isnormal)(t), false);
+ BOOST_CHECK_EQUAL((::boost::math::isnormal)(-t), false);
+ BOOST_CHECK_EQUAL((::boost::math::fpclassify)(t), (::boost::math::fpclassify)(t + 0));
+ // infinity:
+ if(std::numeric_limits<T>::has_infinity)
+ {
+ // At least one std::numeric_limits<T>::infinity)() returns zero
+ // (Compaq true64 cxx), hence the check.
+ t = (std::numeric_limits<T>::infinity)();
+ BOOST_CHECK_EQUAL((::boost::math::fpclassify)(t), (int)FP_INFINITE);
+ BOOST_CHECK_EQUAL((::boost::math::fpclassify)(-t), (int)FP_INFINITE);
+ BOOST_CHECK_EQUAL((::boost::math::isfinite)(t), false);
+ BOOST_CHECK_EQUAL((::boost::math::isfinite)(-t), false);
+ BOOST_CHECK_EQUAL((::boost::math::isinf)(t), true);
+ BOOST_CHECK_EQUAL((::boost::math::isinf)(-t), true);
+ BOOST_CHECK_EQUAL((::boost::math::isnan)(t), false);
+ BOOST_CHECK_EQUAL((::boost::math::isnan)(-t), false);
+ BOOST_CHECK_EQUAL((::boost::math::isnormal)(t), false);
+ BOOST_CHECK_EQUAL((::boost::math::isnormal)(-t), false);
+ BOOST_CHECK_EQUAL((::boost::math::fpclassify)(t), (::boost::math::fpclassify)(t + 0));
+#if !defined(__BORLANDC__) && !(defined(__DECCXX) && !defined(_IEEE_FP))
+ // divide by zero on Borland triggers a C++ exception :-(
+ // divide by zero on Compaq CXX triggers a C style signal :-(
+ t = 2;
+ u = 0;
+ t /= u;
+ BOOST_CHECK_EQUAL((::boost::math::fpclassify)(t), (int)FP_INFINITE);
+ BOOST_CHECK_EQUAL((::boost::math::fpclassify)(-t), (int)FP_INFINITE);
+ BOOST_CHECK_EQUAL((::boost::math::isfinite)(t), false);
+ BOOST_CHECK_EQUAL((::boost::math::isfinite)(-t), false);
+ BOOST_CHECK_EQUAL((::boost::math::isinf)(t), true);
+ BOOST_CHECK_EQUAL((::boost::math::isinf)(-t), true);
+ BOOST_CHECK_EQUAL((::boost::math::isnan)(t), false);
+ BOOST_CHECK_EQUAL((::boost::math::isnan)(-t), false);
+ BOOST_CHECK_EQUAL((::boost::math::isnormal)(t), false);
+ BOOST_CHECK_EQUAL((::boost::math::isnormal)(-t), false);
+ BOOST_CHECK_EQUAL((::boost::math::fpclassify)(t), (::boost::math::fpclassify)(t + 0));
+ t = -2;
+ t /= u;
+ BOOST_CHECK_EQUAL((::boost::math::fpclassify)(t), (int)FP_INFINITE);
+ BOOST_CHECK_EQUAL((::boost::math::fpclassify)(-t), (int)FP_INFINITE);
+ BOOST_CHECK_EQUAL((::boost::math::isfinite)(t), false);
+ BOOST_CHECK_EQUAL((::boost::math::isfinite)(-t), false);
+ BOOST_CHECK_EQUAL((::boost::math::isinf)(t), true);
+ BOOST_CHECK_EQUAL((::boost::math::isinf)(-t), true);
+ BOOST_CHECK_EQUAL((::boost::math::isnan)(t), false);
+ BOOST_CHECK_EQUAL((::boost::math::isnan)(-t), false);
+ BOOST_CHECK_EQUAL((::boost::math::isnormal)(t), false);
+ BOOST_CHECK_EQUAL((::boost::math::isnormal)(-t), false);
+ BOOST_CHECK_EQUAL((::boost::math::fpclassify)(t), (::boost::math::fpclassify)(t + 0));
+#else
+ std::cout << "Infinities from divide by zero not tested" << std::endl;
+#endif
+ }
+ else
+ {
+ std::cout << "Infinity not tested" << std::endl;
+ }
+#ifndef __BORLANDC__
+ // NaN's:
+ // Note that Borland throws an exception if we even try to obtain a Nan
+ // by calling std::numeric_limits<T>::quiet_NaN() !!!!!!!
+ if(std::numeric_limits<T>::has_quiet_NaN)
+ {
+ t = std::numeric_limits<T>::quiet_NaN();
+ BOOST_CHECK_EQUAL((::boost::math::fpclassify)(t), (int)FP_NAN);
+ BOOST_CHECK_EQUAL((::boost::math::fpclassify)(-t), (int)FP_NAN);
+ BOOST_CHECK_EQUAL((::boost::math::isfinite)(t), false);
+ BOOST_CHECK_EQUAL((::boost::math::isfinite)(-t), false);
+ BOOST_CHECK_EQUAL((::boost::math::isinf)(t), false);
+ BOOST_CHECK_EQUAL((::boost::math::isinf)(-t), false);
+ BOOST_CHECK_EQUAL((::boost::math::isnan)(t), true);
+ BOOST_CHECK_EQUAL((::boost::math::isnan)(-t), true);
+ BOOST_CHECK_EQUAL((::boost::math::isnormal)(t), false);
+ BOOST_CHECK_EQUAL((::boost::math::isnormal)(-t), false);
+ }
+ else
+ {
+ std::cout << "Quiet NaN's not tested" << std::endl;
+ }
+ if(std::numeric_limits<T>::has_signaling_NaN)
+ {
+ t = std::numeric_limits<T>::signaling_NaN();
+ BOOST_CHECK_EQUAL((::boost::math::fpclassify)(t), (int)FP_NAN);
+ BOOST_CHECK_EQUAL((::boost::math::fpclassify)(-t), (int)FP_NAN);
+ BOOST_CHECK_EQUAL((::boost::math::isfinite)(t), false);
+ BOOST_CHECK_EQUAL((::boost::math::isfinite)(-t), false);
+ BOOST_CHECK_EQUAL((::boost::math::isinf)(t), false);
+ BOOST_CHECK_EQUAL((::boost::math::isinf)(-t), false);
+ BOOST_CHECK_EQUAL((::boost::math::isnan)(t), true);
+ BOOST_CHECK_EQUAL((::boost::math::isnan)(-t), true);
+ BOOST_CHECK_EQUAL((::boost::math::isnormal)(t), false);
+ BOOST_CHECK_EQUAL((::boost::math::isnormal)(-t), false);
+ }
+ else
+ {
+ std::cout << "Signaling NaN's not tested" << std::endl;
+ }
+#endif
+}
+
+int main()
+{
+ BOOST_MATH_CONTROL_FP;
+ // start by printing some information:
+#ifdef isnan
+ std::cout << "Platform has isnan macro." << std::endl;
+#endif
+#ifdef fpclassify
+ std::cout << "Platform has fpclassify macro." << std::endl;
+#endif
+#ifdef BOOST_HAS_FPCLASSIFY
+ std::cout << "Platform has FP_NORMAL macro." << std::endl;
+#endif
+ std::cout << "FP_ZERO: " << (int)FP_ZERO << std::endl;
+ std::cout << "FP_NORMAL: " << (int)FP_NORMAL << std::endl;
+ std::cout << "FP_INFINITE: " << (int)FP_INFINITE << std::endl;
+ std::cout << "FP_NAN: " << (int)FP_NAN << std::endl;
+ std::cout << "FP_SUBNORMAL: " << (int)FP_SUBNORMAL << std::endl;
+
+#ifdef TEST_MPF_50
+ test<boost::multiprecision::mpf_float_50>();
+ test<boost::multiprecision::mpf_float_100>();
+#endif
+#ifdef TEST_MPFR_50
+ test<boost::multiprecision::mpfr_float_50>();
+ test<boost::multiprecision::mpfr_float_100>();
+#endif
+#ifdef TEST_MP_FLOAT
+ test<boost::multiprecision::mp_float_50>();
+ test<boost::multiprecision::mp_float_100>();
+#endif
+#ifdef TEST_BACKEND
+ test<boost::multiprecision::mp_number<boost::multiprecision::concepts::mp_number_backend_float_architype> >();
+#endif
+ return boost::report_errors();
+}
+

Modified: sandbox/big_number/libs/multiprecision/test/test_round.cpp
==============================================================================
--- sandbox/big_number/libs/multiprecision/test/test_round.cpp (original)
+++ sandbox/big_number/libs/multiprecision/test/test_round.cpp 2011-11-12 07:15:04 EST (Sat, 12 Nov 2011)
@@ -4,7 +4,6 @@
 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 
 #include <boost/detail/lightweight_test.hpp>
-#include <boost/test/floating_point_comparison.hpp>
 #include <boost/math/special_functions/round.hpp>
 #include <boost/math/special_functions/trunc.hpp>
 #include <boost/math/special_functions/modf.hpp>


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk