|
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