Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r82885 - in trunk: boost/math/policies boost/multiprecision boost/multiprecision/detail libs/math/test
From: john_at_[hidden]
Date: 2013-02-14 13:20:04


Author: johnmaddock
Date: 2013-02-14 13:20:03 EST (Thu, 14 Feb 2013)
New Revision: 82885
URL: http://svn.boost.org/trac/boost/changeset/82885

Log:
Fix raise_rounding_error to return the correct result (and type) when an error occurs.
Fixes #7905.
Text files modified:
   trunk/boost/math/policies/error_handling.hpp | 18 ++-
   trunk/boost/multiprecision/cpp_dec_float.hpp | 2
   trunk/boost/multiprecision/detail/default_ops.hpp | 28 ++--
   trunk/boost/multiprecision/mpfr.hpp | 2
   trunk/libs/math/test/test_round.cpp | 187 +++++++++++++++++++++++++--------------
   5 files changed, 143 insertions(+), 94 deletions(-)

Modified: trunk/boost/math/policies/error_handling.hpp
==============================================================================
--- trunk/boost/math/policies/error_handling.hpp (original)
+++ trunk/boost/math/policies/error_handling.hpp 2013-02-14 13:20:03 EST (Thu, 14 Feb 2013)
@@ -383,7 +383,7 @@
 }
 
 template <class T, class TargetType>
-inline T raise_rounding_error(
+inline TargetType raise_rounding_error(
            const char* function,
            const char* message,
            const T& val,
@@ -392,11 +392,11 @@
 {
    raise_error<boost::math::rounding_error, T>(function, message, val);
    // we never get here:
- return T(0);
+ return TargetType(0);
 }
 
 template <class T, class TargetType>
-inline T raise_rounding_error(
+inline TargetType raise_rounding_error(
            const char* ,
            const char* ,
            const T& val,
@@ -405,11 +405,12 @@
 {
    // This may or may not do the right thing, but the user asked for the error
    // to be ignored so here we go anyway:
- return std::numeric_limits<T>::is_specialized ? (val > 0 ? (std::numeric_limits<T>::max)() : -(std::numeric_limits<T>::max)()): val;
+ BOOST_STATIC_ASSERT(std::numeric_limits<TargetType>::is_specialized);
+ return val > 0 ? (std::numeric_limits<TargetType>::max)() : (std::numeric_limits<TargetType>::is_integer ? (std::numeric_limits<TargetType>::min)() : -(std::numeric_limits<TargetType>::max)());
 }
 
 template <class T, class TargetType>
-inline T raise_rounding_error(
+inline TargetType raise_rounding_error(
            const char* ,
            const char* ,
            const T& val,
@@ -419,11 +420,12 @@
    errno = ERANGE;
    // This may or may not do the right thing, but the user asked for the error
    // to be silent so here we go anyway:
- return std::numeric_limits<T>::is_specialized ? (val > 0 ? (std::numeric_limits<T>::max)() : -(std::numeric_limits<T>::max)()): val;
+ BOOST_STATIC_ASSERT(std::numeric_limits<TargetType>::is_specialized);
+ return val > 0 ? (std::numeric_limits<TargetType>::max)() : (std::numeric_limits<TargetType>::is_integer ? (std::numeric_limits<TargetType>::min)() : -(std::numeric_limits<TargetType>::max)());
 }
 
 template <class T, class TargetType>
-inline T raise_rounding_error(
+inline TargetType raise_rounding_error(
            const char* function,
            const char* message,
            const T& val,
@@ -542,7 +544,7 @@
 }
 
 template <class T, class TargetType, class Policy>
-inline T raise_rounding_error(const char* function, const char* message, const T& val, const TargetType& t, const Policy&)
+inline TargetType raise_rounding_error(const char* function, const char* message, const T& val, const TargetType& t, const Policy&)
 {
    typedef typename Policy::rounding_error_type policy_type;
    return detail::raise_rounding_error(

Modified: trunk/boost/multiprecision/cpp_dec_float.hpp
==============================================================================
--- trunk/boost/multiprecision/cpp_dec_float.hpp (original)
+++ trunk/boost/multiprecision/cpp_dec_float.hpp 2013-02-14 13:20:03 EST (Thu, 14 Feb 2013)
@@ -2816,7 +2816,7 @@
 {
    if(!x.isfinite())
    {
- result = boost::math::policies::raise_rounding_error("boost::multiprecision::trunc<%1%>(%1%)", 0, number<cpp_dec_float<Digits10, ExponentType, Allocator> >(x), 0, boost::math::policies::policy<>()).backend();
+ result = boost::math::policies::raise_rounding_error("boost::multiprecision::trunc<%1%>(%1%)", 0, number<cpp_dec_float<Digits10, ExponentType, Allocator> >(x), number<cpp_dec_float<Digits10, ExponentType, Allocator> >(x), boost::math::policies::policy<>()).backend();
       return;
    }
    else if(x.isint())

Modified: trunk/boost/multiprecision/detail/default_ops.hpp
==============================================================================
--- trunk/boost/multiprecision/detail/default_ops.hpp (original)
+++ trunk/boost/multiprecision/detail/default_ops.hpp 2013-02-14 13:20:03 EST (Thu, 14 Feb 2013)
@@ -950,7 +950,7 @@
    int c = eval_fpclassify(a);
    if(c == FP_NAN || c == FP_INFINITE)
    {
- result = boost::math::policies::raise_rounding_error("boost::multiprecision::trunc<%1%>(%1%)", 0, number<T>(a), 0, boost::math::policies::policy<>()).backend();
+ result = boost::math::policies::raise_rounding_error("boost::multiprecision::trunc<%1%>(%1%)", 0, number<T>(a), number<T>(a), boost::math::policies::policy<>()).backend();
       return;
    }
    if(eval_get_sign(a) < 0)
@@ -967,7 +967,7 @@
    int c = eval_fpclassify(a);
    if(c == FP_NAN || c == FP_INFINITE)
    {
- result = boost::math::policies::raise_rounding_error("boost::multiprecision::round<%1%>(%1%)", 0, number<T>(a), 0, boost::math::policies::policy<>()).backend();
+ result = boost::math::policies::raise_rounding_error("boost::multiprecision::round<%1%>(%1%)", 0, number<T>(a), number<T>(a), boost::math::policies::policy<>()).backend();
       return;
    }
    if(eval_get_sign(a) < 0)
@@ -1250,7 +1250,7 @@
    typedef typename detail::expression<tag, A1, A2, A3, A4>::result_type number_type;
    number_type r = trunc(v, pol);
    if((r > (std::numeric_limits<int>::max)()) || r < (std::numeric_limits<int>::min)() || !boost::math::isfinite(v))
- return boost::math::policies::raise_rounding_error("boost::multiprecision::itrunc<%1%>(%1%)", 0, number_type(v), 0, pol).template convert_to<int>();
+ return boost::math::policies::raise_rounding_error("boost::multiprecision::itrunc<%1%>(%1%)", 0, number_type(v), 0, pol);
    return r.template convert_to<int>();
 }
 template <class tag, class A1, class A2, class A3, class A4>
@@ -1263,7 +1263,7 @@
 {
    number<Backend, ExpressionTemplates> r = trunc(v, pol);
    if((r > (std::numeric_limits<int>::max)()) || r < (std::numeric_limits<int>::min)() || !boost::math::isfinite(v))
- return boost::math::policies::raise_rounding_error("boost::multiprecision::itrunc<%1%>(%1%)", 0, v, 0, pol).template convert_to<int>();
+ return boost::math::policies::raise_rounding_error("boost::multiprecision::itrunc<%1%>(%1%)", 0, v, 0, pol);
    return r.template convert_to<int>();
 }
 template <class Backend, expression_template_option ExpressionTemplates>
@@ -1277,7 +1277,7 @@
    typedef typename detail::expression<tag, A1, A2, A3, A4>::result_type number_type;
    number_type r = trunc(v, pol);
    if((r > (std::numeric_limits<long>::max)()) || r < (std::numeric_limits<long>::min)() || !boost::math::isfinite(v))
- return boost::math::policies::raise_rounding_error("boost::multiprecision::ltrunc<%1%>(%1%)", 0, number_type(v), 0L, pol).template convert_to<long>();
+ return boost::math::policies::raise_rounding_error("boost::multiprecision::ltrunc<%1%>(%1%)", 0, number_type(v), 0L, pol);
    return r.template convert_to<long>();
 }
 template <class tag, class A1, class A2, class A3, class A4>
@@ -1290,7 +1290,7 @@
 {
    number<T, ExpressionTemplates> r = trunc(v, pol);
    if((r > (std::numeric_limits<long>::max)()) || r < (std::numeric_limits<long>::min)() || !boost::math::isfinite(v))
- return boost::math::policies::raise_rounding_error("boost::multiprecision::ltrunc<%1%>(%1%)", 0, v, 0L, pol).template convert_to<long>();
+ return boost::math::policies::raise_rounding_error("boost::multiprecision::ltrunc<%1%>(%1%)", 0, v, 0L, pol);
    return r.template convert_to<long>();
 }
 template <class T, expression_template_option ExpressionTemplates>
@@ -1305,7 +1305,7 @@
    typedef typename detail::expression<tag, A1, A2, A3, A4>::result_type number_type;
    number_type r = trunc(v, pol);
    if((r > (std::numeric_limits<long long>::max)()) || r < (std::numeric_limits<long long>::min)() || !boost::math::isfinite(v))
- return boost::math::policies::raise_rounding_error("boost::multiprecision::lltrunc<%1%>(%1%)", 0, number_type(v), 0LL, pol).template convert_to<long long>();
+ return boost::math::policies::raise_rounding_error("boost::multiprecision::lltrunc<%1%>(%1%)", 0, number_type(v), 0LL, pol);
    return r.template convert_to<long long>();
 }
 template <class tag, class A1, class A2, class A3, class A4>
@@ -1318,7 +1318,7 @@
 {
    number<T, ExpressionTemplates> r = trunc(v, pol);
    if((r > (std::numeric_limits<long long>::max)()) || r < (std::numeric_limits<long long>::min)() || !boost::math::isfinite(v))
- return boost::math::policies::raise_rounding_error("boost::multiprecision::lltrunc<%1%>(%1%)", 0, v, 0LL, pol).template convert_to<long long>();
+ return boost::math::policies::raise_rounding_error("boost::multiprecision::lltrunc<%1%>(%1%)", 0, v, 0LL, pol);
    return r.template convert_to<long long>();
 }
 template <class T, expression_template_option ExpressionTemplates>
@@ -1348,7 +1348,7 @@
    typedef typename detail::expression<tag, A1, A2, A3, A4>::result_type number_type;
    number_type r = round(v, pol);
    if((r > (std::numeric_limits<int>::max)()) || r < (std::numeric_limits<int>::min)() || !boost::math::isfinite(v))
- return boost::math::policies::raise_rounding_error("boost::multiprecision::iround<%1%>(%1%)", 0, number_type(v), 0, pol).template convert_to<int>();
+ return boost::math::policies::raise_rounding_error("boost::multiprecision::iround<%1%>(%1%)", 0, number_type(v), 0, pol);
    return r.template convert_to<int>();
 }
 template <class tag, class A1, class A2, class A3, class A4>
@@ -1361,7 +1361,7 @@
 {
    number<T, ExpressionTemplates> r = round(v, pol);
    if((r > (std::numeric_limits<int>::max)()) || r < (std::numeric_limits<int>::min)() || !boost::math::isfinite(v))
- return boost::math::policies::raise_rounding_error("boost::multiprecision::iround<%1%>(%1%)", 0, v, 0, pol).template convert_to<int>();
+ return boost::math::policies::raise_rounding_error("boost::multiprecision::iround<%1%>(%1%)", 0, v, 0, pol);
    return r.template convert_to<int>();
 }
 template <class T, expression_template_option ExpressionTemplates>
@@ -1375,7 +1375,7 @@
    typedef typename detail::expression<tag, A1, A2, A3, A4>::result_type number_type;
    number_type r = round(v, pol);
    if((r > (std::numeric_limits<long>::max)()) || r < (std::numeric_limits<long>::min)() || !boost::math::isfinite(v))
- return boost::math::policies::raise_rounding_error("boost::multiprecision::lround<%1%>(%1%)", 0, number_type(v), 0L, pol).template convert_to<long>();
+ return boost::math::policies::raise_rounding_error("boost::multiprecision::lround<%1%>(%1%)", 0, number_type(v), 0L, pol);
    return r.template convert_to<long>();
 }
 template <class tag, class A1, class A2, class A3, class A4>
@@ -1388,7 +1388,7 @@
 {
    number<T, ExpressionTemplates> r = round(v, pol);
    if((r > (std::numeric_limits<long>::max)()) || r < (std::numeric_limits<long>::min)() || !boost::math::isfinite(v))
- return boost::math::policies::raise_rounding_error("boost::multiprecision::lround<%1%>(%1%)", 0, v, 0L, pol).template convert_to<long>();
+ return boost::math::policies::raise_rounding_error("boost::multiprecision::lround<%1%>(%1%)", 0, v, 0L, pol);
    return r.template convert_to<long>();
 }
 template <class T, expression_template_option ExpressionTemplates>
@@ -1403,7 +1403,7 @@
    typedef typename detail::expression<tag, A1, A2, A3, A4>::result_type number_type;
    number_type r = round(v, pol);
    if((r > (std::numeric_limits<long long>::max)()) || r < (std::numeric_limits<long long>::min)() || !boost::math::isfinite(v))
- return boost::math::policies::raise_rounding_error("boost::multiprecision::iround<%1%>(%1%)", 0, number_type(v), 0LL, pol).template convert_to<long long>();
+ return boost::math::policies::raise_rounding_error("boost::multiprecision::iround<%1%>(%1%)", 0, number_type(v), 0LL, pol);
    return r.template convert_to<long long>();
 }
 template <class tag, class A1, class A2, class A3, class A4>
@@ -1416,7 +1416,7 @@
 {
    number<T, ExpressionTemplates> r = round(v, pol);
    if((r > (std::numeric_limits<long long>::max)()) || r < (std::numeric_limits<long long>::min)() || !boost::math::isfinite(v))
- return boost::math::policies::raise_rounding_error("boost::multiprecision::iround<%1%>(%1%)", 0, v, 0LL, pol).template convert_to<long long>();
+ return boost::math::policies::raise_rounding_error("boost::multiprecision::iround<%1%>(%1%)", 0, v, 0LL, pol);
    return r.template convert_to<long long>();
 }
 template <class T, expression_template_option ExpressionTemplates>

Modified: trunk/boost/multiprecision/mpfr.hpp
==============================================================================
--- trunk/boost/multiprecision/mpfr.hpp (original)
+++ trunk/boost/multiprecision/mpfr.hpp 2013-02-14 13:20:03 EST (Thu, 14 Feb 2013)
@@ -1192,7 +1192,7 @@
 {
    if(0 == mpfr_number_p(val.data()))
    {
- result = boost::math::policies::raise_rounding_error("boost::multiprecision::trunc<%1%>(%1%)", 0, number<mpfr_float_backend<Digits10, AllocateType> >(val), 0, boost::math::policies::policy<>()).backend();
+ result = boost::math::policies::raise_rounding_error("boost::multiprecision::trunc<%1%>(%1%)", 0, number<mpfr_float_backend<Digits10, AllocateType> >(val), number<mpfr_float_backend<Digits10, AllocateType> >(val), boost::math::policies::policy<>()).backend();
       return;
    }
    mpfr_trunc(result.data(), val.data());

Modified: trunk/libs/math/test/test_round.cpp
==============================================================================
--- trunk/libs/math/test/test_round.cpp (original)
+++ trunk/libs/math/test/test_round.cpp 2013-02-14 13:20:03 EST (Thu, 14 Feb 2013)
@@ -124,79 +124,82 @@
 void test_round(T, const char* name )
 {
    BOOST_MATH_STD_USING
+#ifdef BOOST_HAS_LONG_LONG
+ using boost::math::llround; using boost::math::lltrunc;
+#endif
 
    std::cout << "Testing rounding with type " << name << std::endl;
 
    for(int i = 0; i < 1000; ++i)
    {
       T arg = get_random<T>();
- T r = boost::math::round(arg);
+ T r = round(arg);
       check_within_half(arg, r);
- r = boost::math::trunc(arg);
+ r = trunc(arg);
       check_trunc_result(arg, r);
- T frac = boost::math::modf(arg, &r);
+ T frac = modf(arg, &r);
       check_modf_result(arg, frac, r);
 
       if(abs(r) < (std::numeric_limits<int>::max)())
       {
- int i = boost::math::iround(arg);
+ int i = iround(arg);
          check_within_half(arg, i);
- i = boost::math::itrunc(arg);
+ i = itrunc(arg);
          check_trunc_result(arg, i);
- r = boost::math::modf(arg, &i);
+ r = modf(arg, &i);
          check_modf_result(arg, r, i);
       }
       if(std::numeric_limits<T>::digits >= std::numeric_limits<int>::digits)
       {
- int si = boost::math::iround(static_cast<T>((std::numeric_limits<int>::max)()));
+ int si = iround(static_cast<T>((std::numeric_limits<int>::max)()));
          check_within_half(static_cast<T>((std::numeric_limits<int>::max)()), si);
- si = boost::math::iround(static_cast<T>((std::numeric_limits<int>::min)()));
+ si = iround(static_cast<T>((std::numeric_limits<int>::min)()));
          check_within_half(static_cast<T>((std::numeric_limits<int>::min)()), si);
- si = boost::math::itrunc(static_cast<T>((std::numeric_limits<int>::max)()));
+ si = itrunc(static_cast<T>((std::numeric_limits<int>::max)()));
          check_trunc_result(static_cast<T>((std::numeric_limits<int>::max)()), si);
- si = boost::math::itrunc(static_cast<T>((std::numeric_limits<int>::min)()));
+ si = itrunc(static_cast<T>((std::numeric_limits<int>::min)()));
          check_trunc_result(static_cast<T>((std::numeric_limits<int>::min)()), si);
       }
       if(abs(r) < (std::numeric_limits<long>::max)())
       {
- long l = boost::math::lround(arg);
+ long l = lround(arg);
          check_within_half(arg, l);
- l = boost::math::ltrunc(arg);
+ l = ltrunc(arg);
          check_trunc_result(arg, l);
- r = boost::math::modf(arg, &l);
+ r = modf(arg, &l);
          check_modf_result(arg, r, l);
       }
       if(std::numeric_limits<T>::digits >= std::numeric_limits<long>::digits)
       {
- long k = boost::math::lround(static_cast<T>((std::numeric_limits<long>::max)()));
+ long k = lround(static_cast<T>((std::numeric_limits<long>::max)()));
          check_within_half(static_cast<T>((std::numeric_limits<long>::max)()), k);
- k = boost::math::lround(static_cast<T>((std::numeric_limits<long>::min)()));
+ k = lround(static_cast<T>((std::numeric_limits<long>::min)()));
          check_within_half(static_cast<T>((std::numeric_limits<long>::min)()), k);
- k = boost::math::ltrunc(static_cast<T>((std::numeric_limits<long>::max)()));
+ k = ltrunc(static_cast<T>((std::numeric_limits<long>::max)()));
          check_trunc_result(static_cast<T>((std::numeric_limits<long>::max)()), k);
- k = boost::math::ltrunc(static_cast<T>((std::numeric_limits<long>::min)()));
+ k = ltrunc(static_cast<T>((std::numeric_limits<long>::min)()));
          check_trunc_result(static_cast<T>((std::numeric_limits<long>::min)()), k);
       }
 
 #ifdef BOOST_HAS_LONG_LONG
       if(abs(r) < (std::numeric_limits<boost::long_long_type>::max)())
       {
- boost::long_long_type ll = boost::math::llround(arg);
+ boost::long_long_type ll = llround(arg);
          check_within_half(arg, ll);
- ll = boost::math::lltrunc(arg);
+ ll = lltrunc(arg);
          check_trunc_result(arg, ll);
- r = boost::math::modf(arg, &ll);
+ r = modf(arg, &ll);
          check_modf_result(arg, r, ll);
       }
       if(std::numeric_limits<T>::digits >= std::numeric_limits<boost::long_long_type>::digits)
       {
- boost::long_long_type j = boost::math::llround(static_cast<T>((std::numeric_limits<boost::long_long_type>::max)()));
+ boost::long_long_type j = llround(static_cast<T>((std::numeric_limits<boost::long_long_type>::max)()));
          check_within_half(static_cast<T>((std::numeric_limits<boost::long_long_type>::max)()), j);
- j = boost::math::llround(static_cast<T>((std::numeric_limits<boost::long_long_type>::min)()));
+ j = llround(static_cast<T>((std::numeric_limits<boost::long_long_type>::min)()));
          check_within_half(static_cast<T>((std::numeric_limits<boost::long_long_type>::min)()), j);
- j = boost::math::lltrunc(static_cast<T>((std::numeric_limits<boost::long_long_type>::max)()));
+ j = lltrunc(static_cast<T>((std::numeric_limits<boost::long_long_type>::max)()));
          check_trunc_result(static_cast<T>((std::numeric_limits<boost::long_long_type>::max)()), j);
- j = boost::math::lltrunc(static_cast<T>((std::numeric_limits<boost::long_long_type>::min)()));
+ j = lltrunc(static_cast<T>((std::numeric_limits<boost::long_long_type>::min)()));
          check_trunc_result(static_cast<T>((std::numeric_limits<boost::long_long_type>::min)()), j);
       }
 #endif
@@ -204,98 +207,142 @@
    //
    // Finish off by testing the error handlers:
    //
- BOOST_CHECK_THROW(boost::math::iround(static_cast<T>(1e20)), boost::math::rounding_error);
- BOOST_CHECK_THROW(boost::math::iround(static_cast<T>(-1e20)), boost::math::rounding_error);
- BOOST_CHECK_THROW(boost::math::lround(static_cast<T>(1e20)), boost::math::rounding_error);
- BOOST_CHECK_THROW(boost::math::lround(static_cast<T>(-1e20)), boost::math::rounding_error);
+ BOOST_CHECK_THROW(iround(static_cast<T>(1e20)), boost::math::rounding_error);
+ BOOST_CHECK_THROW(iround(static_cast<T>(-1e20)), boost::math::rounding_error);
+ BOOST_CHECK_THROW(lround(static_cast<T>(1e20)), boost::math::rounding_error);
+ BOOST_CHECK_THROW(lround(static_cast<T>(-1e20)), boost::math::rounding_error);
 #ifdef BOOST_HAS_LONG_LONG
- BOOST_CHECK_THROW(boost::math::llround(static_cast<T>(1e20)), boost::math::rounding_error);
- BOOST_CHECK_THROW(boost::math::llround(static_cast<T>(-1e20)), boost::math::rounding_error);
+ BOOST_CHECK_THROW(llround(static_cast<T>(1e20)), boost::math::rounding_error);
+ BOOST_CHECK_THROW(llround(static_cast<T>(-1e20)), boost::math::rounding_error);
 #endif
    if(std::numeric_limits<T>::has_infinity)
    {
- BOOST_CHECK_THROW(boost::math::round(std::numeric_limits<T>::infinity()), boost::math::rounding_error);
- BOOST_CHECK_THROW(boost::math::iround(std::numeric_limits<T>::infinity()), boost::math::rounding_error);
- BOOST_CHECK_THROW(boost::math::iround(-std::numeric_limits<T>::infinity()), boost::math::rounding_error);
- BOOST_CHECK_THROW(boost::math::lround(std::numeric_limits<T>::infinity()), boost::math::rounding_error);
- BOOST_CHECK_THROW(boost::math::lround(-std::numeric_limits<T>::infinity()), boost::math::rounding_error);
+ BOOST_CHECK_THROW(round(std::numeric_limits<T>::infinity()), boost::math::rounding_error);
+ BOOST_CHECK_THROW(iround(std::numeric_limits<T>::infinity()), boost::math::rounding_error);
+ BOOST_CHECK_THROW(iround(-std::numeric_limits<T>::infinity()), boost::math::rounding_error);
+ BOOST_CHECK_THROW(lround(std::numeric_limits<T>::infinity()), boost::math::rounding_error);
+ BOOST_CHECK_THROW(lround(-std::numeric_limits<T>::infinity()), boost::math::rounding_error);
    #ifdef BOOST_HAS_LONG_LONG
- BOOST_CHECK_THROW(boost::math::llround(std::numeric_limits<T>::infinity()), boost::math::rounding_error);
- BOOST_CHECK_THROW(boost::math::llround(-std::numeric_limits<T>::infinity()), boost::math::rounding_error);
+ BOOST_CHECK_THROW(llround(std::numeric_limits<T>::infinity()), boost::math::rounding_error);
+ BOOST_CHECK_THROW(llround(-std::numeric_limits<T>::infinity()), boost::math::rounding_error);
    #endif
    }
    if(std::numeric_limits<T>::has_quiet_NaN)
    {
- BOOST_CHECK_THROW(boost::math::round(std::numeric_limits<T>::quiet_NaN()), boost::math::rounding_error);
- BOOST_CHECK_THROW(boost::math::iround(std::numeric_limits<T>::quiet_NaN()), boost::math::rounding_error);
- BOOST_CHECK_THROW(boost::math::lround(std::numeric_limits<T>::quiet_NaN()), boost::math::rounding_error);
+ BOOST_CHECK_THROW(round(std::numeric_limits<T>::quiet_NaN()), boost::math::rounding_error);
+ BOOST_CHECK_THROW(iround(std::numeric_limits<T>::quiet_NaN()), boost::math::rounding_error);
+ BOOST_CHECK_THROW(lround(std::numeric_limits<T>::quiet_NaN()), boost::math::rounding_error);
    #ifdef BOOST_HAS_LONG_LONG
- BOOST_CHECK_THROW(boost::math::llround(std::numeric_limits<T>::quiet_NaN()), boost::math::rounding_error);
+ BOOST_CHECK_THROW(llround(std::numeric_limits<T>::quiet_NaN()), boost::math::rounding_error);
    #endif
    }
- BOOST_CHECK_THROW(boost::math::itrunc(static_cast<T>(1e20)), boost::math::rounding_error);
- BOOST_CHECK_THROW(boost::math::itrunc(static_cast<T>(-1e20)), boost::math::rounding_error);
- BOOST_CHECK_THROW(boost::math::ltrunc(static_cast<T>(1e20)), boost::math::rounding_error);
- BOOST_CHECK_THROW(boost::math::ltrunc(static_cast<T>(-1e20)), boost::math::rounding_error);
+ BOOST_CHECK_THROW(itrunc(static_cast<T>(1e20)), boost::math::rounding_error);
+ BOOST_CHECK_THROW(itrunc(static_cast<T>(-1e20)), boost::math::rounding_error);
+ BOOST_CHECK_THROW(ltrunc(static_cast<T>(1e20)), boost::math::rounding_error);
+ BOOST_CHECK_THROW(ltrunc(static_cast<T>(-1e20)), boost::math::rounding_error);
 #ifdef BOOST_HAS_LONG_LONG
- BOOST_CHECK_THROW(boost::math::lltrunc(static_cast<T>(1e20)), boost::math::rounding_error);
- BOOST_CHECK_THROW(boost::math::lltrunc(static_cast<T>(-1e20)), boost::math::rounding_error);
+ BOOST_CHECK_THROW(lltrunc(static_cast<T>(1e20)), boost::math::rounding_error);
+ BOOST_CHECK_THROW(lltrunc(static_cast<T>(-1e20)), boost::math::rounding_error);
 #endif
    if(std::numeric_limits<T>::has_infinity)
    {
- BOOST_CHECK_THROW(boost::math::trunc(std::numeric_limits<T>::infinity()), boost::math::rounding_error);
- BOOST_CHECK_THROW(boost::math::itrunc(std::numeric_limits<T>::infinity()), boost::math::rounding_error);
- BOOST_CHECK_THROW(boost::math::itrunc(-std::numeric_limits<T>::infinity()), boost::math::rounding_error);
- BOOST_CHECK_THROW(boost::math::ltrunc(std::numeric_limits<T>::infinity()), boost::math::rounding_error);
- BOOST_CHECK_THROW(boost::math::ltrunc(-std::numeric_limits<T>::infinity()), boost::math::rounding_error);
+ BOOST_CHECK_THROW(trunc(std::numeric_limits<T>::infinity()), boost::math::rounding_error);
+ BOOST_CHECK_THROW(itrunc(std::numeric_limits<T>::infinity()), boost::math::rounding_error);
+ BOOST_CHECK_THROW(itrunc(-std::numeric_limits<T>::infinity()), boost::math::rounding_error);
+ BOOST_CHECK_THROW(ltrunc(std::numeric_limits<T>::infinity()), boost::math::rounding_error);
+ BOOST_CHECK_THROW(ltrunc(-std::numeric_limits<T>::infinity()), boost::math::rounding_error);
    #ifdef BOOST_HAS_LONG_LONG
- BOOST_CHECK_THROW(boost::math::lltrunc(std::numeric_limits<T>::infinity()), boost::math::rounding_error);
- BOOST_CHECK_THROW(boost::math::lltrunc(-std::numeric_limits<T>::infinity()), boost::math::rounding_error);
+ BOOST_CHECK_THROW(lltrunc(std::numeric_limits<T>::infinity()), boost::math::rounding_error);
+ BOOST_CHECK_THROW(lltrunc(-std::numeric_limits<T>::infinity()), boost::math::rounding_error);
    #endif
    }
    if(std::numeric_limits<T>::has_quiet_NaN)
    {
- BOOST_CHECK_THROW(boost::math::trunc(std::numeric_limits<T>::quiet_NaN()), boost::math::rounding_error);
- BOOST_CHECK_THROW(boost::math::itrunc(std::numeric_limits<T>::quiet_NaN()), boost::math::rounding_error);
- BOOST_CHECK_THROW(boost::math::ltrunc(std::numeric_limits<T>::quiet_NaN()), boost::math::rounding_error);
+ BOOST_CHECK_THROW(trunc(std::numeric_limits<T>::quiet_NaN()), boost::math::rounding_error);
+ BOOST_CHECK_THROW(itrunc(std::numeric_limits<T>::quiet_NaN()), boost::math::rounding_error);
+ BOOST_CHECK_THROW(ltrunc(std::numeric_limits<T>::quiet_NaN()), boost::math::rounding_error);
    #ifdef BOOST_HAS_LONG_LONG
- BOOST_CHECK_THROW(boost::math::lltrunc(std::numeric_limits<T>::quiet_NaN()), boost::math::rounding_error);
+ BOOST_CHECK_THROW(lltrunc(std::numeric_limits<T>::quiet_NaN()), boost::math::rounding_error);
    #endif
    }
    if(std::numeric_limits<T>::digits >= std::numeric_limits<int>::digits)
    {
- BOOST_CHECK_THROW(boost::math::itrunc(static_cast<T>((std::numeric_limits<int>::max)()) + 1), boost::math::rounding_error);
- BOOST_CHECK_THROW(boost::math::itrunc(static_cast<T>((std::numeric_limits<int>::min)()) - 1), boost::math::rounding_error);
+ BOOST_CHECK_THROW(itrunc(static_cast<T>((std::numeric_limits<int>::max)()) + 1), boost::math::rounding_error);
+ BOOST_CHECK_THROW(itrunc(static_cast<T>((std::numeric_limits<int>::min)()) - 1), boost::math::rounding_error);
    }
    if(std::numeric_limits<T>::digits >= std::numeric_limits<long>::digits)
    {
- BOOST_CHECK_THROW(boost::math::ltrunc(static_cast<T>((std::numeric_limits<long>::max)()) + 1), boost::math::rounding_error);
- BOOST_CHECK_THROW(boost::math::ltrunc(static_cast<T>((std::numeric_limits<long>::min)()) - 1), boost::math::rounding_error);
+ BOOST_CHECK_THROW(ltrunc(static_cast<T>((std::numeric_limits<long>::max)()) + 1), boost::math::rounding_error);
+ BOOST_CHECK_THROW(ltrunc(static_cast<T>((std::numeric_limits<long>::min)()) - 1), boost::math::rounding_error);
    }
 #ifndef BOOST_NO_LONG_LONG
    if(std::numeric_limits<T>::digits >= std::numeric_limits<boost::long_long_type>::digits)
    {
- BOOST_CHECK_THROW(boost::math::lltrunc(static_cast<T>((std::numeric_limits<boost::long_long_type>::max)()) + 1), boost::math::rounding_error);
- BOOST_CHECK_THROW(boost::math::lltrunc(static_cast<T>((std::numeric_limits<boost::long_long_type>::min)()) - 1), boost::math::rounding_error);
+ BOOST_CHECK_THROW(lltrunc(static_cast<T>((std::numeric_limits<boost::long_long_type>::max)()) + 1), boost::math::rounding_error);
+ BOOST_CHECK_THROW(lltrunc(static_cast<T>((std::numeric_limits<boost::long_long_type>::min)()) - 1), boost::math::rounding_error);
    }
 #endif
    if(std::numeric_limits<T>::digits >= std::numeric_limits<int>::digits)
    {
- BOOST_CHECK_THROW(boost::math::iround(static_cast<T>((std::numeric_limits<int>::max)()) + 1), boost::math::rounding_error);
- BOOST_CHECK_THROW(boost::math::iround(static_cast<T>((std::numeric_limits<int>::min)()) - 1), boost::math::rounding_error);
+ BOOST_CHECK_THROW(iround(static_cast<T>((std::numeric_limits<int>::max)()) + 1), boost::math::rounding_error);
+ BOOST_CHECK_THROW(iround(static_cast<T>((std::numeric_limits<int>::min)()) - 1), boost::math::rounding_error);
    }
    if(std::numeric_limits<T>::digits >= std::numeric_limits<long>::digits)
    {
- BOOST_CHECK_THROW(boost::math::lround(static_cast<T>((std::numeric_limits<long>::max)()) + 1), boost::math::rounding_error);
- BOOST_CHECK_THROW(boost::math::lround(static_cast<T>((std::numeric_limits<long>::min)()) - 1), boost::math::rounding_error);
+ BOOST_CHECK_THROW(lround(static_cast<T>((std::numeric_limits<long>::max)()) + 1), boost::math::rounding_error);
+ BOOST_CHECK_THROW(lround(static_cast<T>((std::numeric_limits<long>::min)()) - 1), boost::math::rounding_error);
    }
 #ifndef BOOST_NO_LONG_LONG
    if(std::numeric_limits<T>::digits >= std::numeric_limits<boost::long_long_type>::digits)
    {
- BOOST_CHECK_THROW(boost::math::llround(static_cast<T>((std::numeric_limits<boost::long_long_type>::max)()) + 1), boost::math::rounding_error);
- BOOST_CHECK_THROW(boost::math::llround(static_cast<T>((std::numeric_limits<boost::long_long_type>::min)()) - 1), boost::math::rounding_error);
+ BOOST_CHECK_THROW(llround(static_cast<T>((std::numeric_limits<boost::long_long_type>::max)()) + 1), boost::math::rounding_error);
+ BOOST_CHECK_THROW(llround(static_cast<T>((std::numeric_limits<boost::long_long_type>::min)()) - 1), boost::math::rounding_error);
    }
 #endif
+ //
+ // try non-throwing error handlers:
+ //
+ boost::math::policies::policy<boost::math::policies::rounding_error<boost::math::policies::ignore_error> > pol;
+
+ if(std::numeric_limits<T>::digits >= std::numeric_limits<int>::digits)
+ {
+ BOOST_CHECK_EQUAL(iround((std::numeric_limits<int>::max)() + T(1.0), pol), (std::numeric_limits<int>::max)());
+ BOOST_CHECK_EQUAL(iround((std::numeric_limits<int>::min)() - T(1.0), pol), (std::numeric_limits<int>::min)());
+ BOOST_CHECK_EQUAL(itrunc((std::numeric_limits<int>::max)() + T(1.0), pol), (std::numeric_limits<int>::max)());
+ BOOST_CHECK_EQUAL(itrunc((std::numeric_limits<int>::min)() - T(1.0), pol), (std::numeric_limits<int>::min)());
+ }
+ if(std::numeric_limits<T>::digits >= std::numeric_limits<long>::digits)
+ {
+ BOOST_CHECK_EQUAL(lround((std::numeric_limits<long>::max)() + T(1.0), pol), (std::numeric_limits<long>::max)());
+ BOOST_CHECK_EQUAL(lround((std::numeric_limits<long>::min)() - T(1.0), pol), (std::numeric_limits<long>::min)());
+ BOOST_CHECK_EQUAL(ltrunc((std::numeric_limits<long>::max)() + T(1.0), pol), (std::numeric_limits<long>::max)());
+ BOOST_CHECK_EQUAL(ltrunc((std::numeric_limits<long>::min)() - T(1.0), pol), (std::numeric_limits<long>::min)());
+ }
+#ifndef BOOST_NO_LONG_LONG
+ if(std::numeric_limits<T>::digits >= std::numeric_limits<long long>::digits)
+ {
+ BOOST_CHECK_EQUAL(llround((std::numeric_limits<long long>::max)() + T(1.0), pol), (std::numeric_limits<long long>::max)());
+ BOOST_CHECK_EQUAL(llround((std::numeric_limits<long long>::min)() - T(1.0), pol), (std::numeric_limits<long long>::min)());
+ BOOST_CHECK_EQUAL(lltrunc((std::numeric_limits<long long>::max)() + T(1.0), pol), (std::numeric_limits<long long>::max)());
+ BOOST_CHECK_EQUAL(lltrunc((std::numeric_limits<long long>::min)() - T(1.0), pol), (std::numeric_limits<long long>::min)());
+ }
+#endif
+ // Again with bigger value:
+ T big = 1e20f;
+ BOOST_CHECK_EQUAL(iround(big, pol), (std::numeric_limits<int>::max)());
+ BOOST_CHECK_EQUAL(lround(big, pol), (std::numeric_limits<long>::max)());
+ BOOST_CHECK_EQUAL(iround(-big, pol), (std::numeric_limits<int>::min)());
+ BOOST_CHECK_EQUAL(lround(-big, pol), (std::numeric_limits<long>::min)());
+ BOOST_CHECK_EQUAL(itrunc(big, pol), (std::numeric_limits<int>::max)());
+ BOOST_CHECK_EQUAL(ltrunc(big, pol), (std::numeric_limits<long>::max)());
+ BOOST_CHECK_EQUAL(itrunc(-big, pol), (std::numeric_limits<int>::min)());
+ BOOST_CHECK_EQUAL(ltrunc(-big, pol), (std::numeric_limits<long>::min)());
+#ifndef BOOST_NO_LONG_LONG
+ BOOST_CHECK_EQUAL(llround(big, pol), (std::numeric_limits<long long>::max)());
+ BOOST_CHECK_EQUAL(llround(-big, pol), (std::numeric_limits<long long>::min)());
+ BOOST_CHECK_EQUAL(lltrunc(big, pol), (std::numeric_limits<long long>::max)());
+ BOOST_CHECK_EQUAL(lltrunc(-big, pol), (std::numeric_limits<long long>::min)());
+#endif
 }
 
 BOOST_AUTO_TEST_CASE( test_main )


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