summaryrefslogtreecommitdiff
path: root/boost/math/tools/precision.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'boost/math/tools/precision.hpp')
-rw-r--r--boost/math/tools/precision.hpp136
1 files changed, 66 insertions, 70 deletions
diff --git a/boost/math/tools/precision.hpp b/boost/math/tools/precision.hpp
index ed146c458f..9631fc2eb6 100644
--- a/boost/math/tools/precision.hpp
+++ b/boost/math/tools/precision.hpp
@@ -39,7 +39,7 @@ namespace tools
// See Conceptual Requirements for Real Number Types.
template <class T>
-inline int digits(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC(T))
+inline BOOST_MATH_CONSTEXPR int digits(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC(T)) BOOST_NOEXCEPT
{
#ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
BOOST_STATIC_ASSERT( ::std::numeric_limits<T>::is_specialized);
@@ -54,7 +54,7 @@ inline int digits(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC(T))
}
template <class T>
-inline T max_value(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE(T))
+inline BOOST_MATH_CONSTEXPR T max_value(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE(T)) BOOST_MATH_NOEXCEPT(T)
{
#ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
BOOST_STATIC_ASSERT( ::std::numeric_limits<T>::is_specialized);
@@ -66,7 +66,7 @@ inline T max_value(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE(T))
// -max_value<double> = -1.79769e+308, max_value<double> = 1.79769e+308.
template <class T>
-inline T min_value(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE(T))
+inline BOOST_MATH_CONSTEXPR T min_value(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE(T)) BOOST_MATH_NOEXCEPT(T)
{
#ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
BOOST_STATIC_ASSERT( ::std::numeric_limits<T>::is_specialized);
@@ -86,13 +86,13 @@ namespace detail{
// For type float first:
//
template <class T>
-inline T log_max_value(const mpl::int_<128>& BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_TYPE(T))
+inline BOOST_MATH_CONSTEXPR T log_max_value(const mpl::int_<128>& BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_TYPE(T)) BOOST_MATH_NOEXCEPT(T)
{
return 88.0f;
}
template <class T>
-inline T log_min_value(const mpl::int_<128>& BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_TYPE(T))
+inline BOOST_MATH_CONSTEXPR T log_min_value(const mpl::int_<128>& BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_TYPE(T)) BOOST_MATH_NOEXCEPT(T)
{
return -87.0f;
}
@@ -100,13 +100,13 @@ inline T log_min_value(const mpl::int_<128>& BOOST_MATH_APPEND_EXPLICIT_TEMPLATE
// Now double:
//
template <class T>
-inline T log_max_value(const mpl::int_<1024>& BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_TYPE(T))
+inline BOOST_MATH_CONSTEXPR T log_max_value(const mpl::int_<1024>& BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_TYPE(T)) BOOST_MATH_NOEXCEPT(T)
{
return 709.0;
}
template <class T>
-inline T log_min_value(const mpl::int_<1024>& BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_TYPE(T))
+inline BOOST_MATH_CONSTEXPR T log_min_value(const mpl::int_<1024>& BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_TYPE(T)) BOOST_MATH_NOEXCEPT(T)
{
return -708.0;
}
@@ -114,13 +114,13 @@ inline T log_min_value(const mpl::int_<1024>& BOOST_MATH_APPEND_EXPLICIT_TEMPLAT
// 80 and 128-bit long doubles:
//
template <class T>
-inline T log_max_value(const mpl::int_<16384>& BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_TYPE(T))
+inline BOOST_MATH_CONSTEXPR T log_max_value(const mpl::int_<16384>& BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_TYPE(T)) BOOST_MATH_NOEXCEPT(T)
{
return 11356.0L;
}
template <class T>
-inline T log_min_value(const mpl::int_<16384>& BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_TYPE(T))
+inline BOOST_MATH_CONSTEXPR T log_min_value(const mpl::int_<16384>& BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_TYPE(T)) BOOST_MATH_NOEXCEPT(T)
{
return -11355.0L;
}
@@ -128,17 +128,12 @@ inline T log_min_value(const mpl::int_<16384>& BOOST_MATH_APPEND_EXPLICIT_TEMPLA
template <class T>
inline T log_max_value(const mpl::int_<0>& BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_TYPE(T))
{
-#ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
- BOOST_STATIC_ASSERT( ::std::numeric_limits<T>::is_specialized);
-#else
- BOOST_ASSERT(::std::numeric_limits<T>::is_specialized);
-#endif
BOOST_MATH_STD_USING
#ifdef __SUNPRO_CC
- static const T m = (std::numeric_limits<T>::max)();
+ static const T m = boost::math::tools::max_value<T>();
static const T val = log(m);
#else
- static const T val = log((std::numeric_limits<T>::max)());
+ static const T val = log(boost::math::tools::max_value<T>());
#endif
return val;
}
@@ -146,30 +141,25 @@ inline T log_max_value(const mpl::int_<0>& BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_T
template <class T>
inline T log_min_value(const mpl::int_<0>& BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_TYPE(T))
{
-#ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
- BOOST_STATIC_ASSERT( ::std::numeric_limits<T>::is_specialized);
-#else
- BOOST_ASSERT(::std::numeric_limits<T>::is_specialized);
-#endif
BOOST_MATH_STD_USING
#ifdef __SUNPRO_CC
- static const T m = (std::numeric_limits<T>::min)();
+ static const T m = boost::math::tools::min_value<T>();
static const T val = log(m);
#else
- static const T val = log((std::numeric_limits<T>::min)());
+ static const T val = log(boost::math::tools::min_value<T>());
#endif
return val;
}
template <class T>
-inline T epsilon(const mpl::true_& BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_TYPE(T))
+inline BOOST_MATH_CONSTEXPR T epsilon(const mpl::true_& BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_TYPE(T)) BOOST_MATH_NOEXCEPT(T)
{
return std::numeric_limits<T>::epsilon();
}
#if defined(__GNUC__) && ((LDBL_MANT_DIG == 106) || (__LDBL_MANT_DIG__ == 106))
template <>
-inline long double epsilon<long double>(const mpl::true_& BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_TYPE(long double))
+inline BOOST_MATH_CONSTEXPR long double epsilon<long double>(const mpl::true_& BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_TYPE(long double)) BOOST_MATH_NOEXCEPT(long double)
{
// numeric_limits on Darwin (and elsewhere) tells lies here:
// the issue is that long double on a few platforms is
@@ -195,6 +185,27 @@ inline T epsilon(const mpl::false_& BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_TYPE(T))
return eps;
}
+template <class T>
+struct log_limit_traits
+{
+ typedef typename mpl::if_c<
+ (std::numeric_limits<T>::radix == 2) &&
+ (std::numeric_limits<T>::max_exponent == 128
+ || std::numeric_limits<T>::max_exponent == 1024
+ || std::numeric_limits<T>::max_exponent == 16384),
+ mpl::int_<(std::numeric_limits<T>::max_exponent > INT_MAX ? INT_MAX : static_cast<int>(std::numeric_limits<T>::max_exponent))>,
+ mpl::int_<0>
+ >::type tag_type;
+ BOOST_STATIC_CONSTANT(bool, value = tag_type::value ? true : false);
+ BOOST_STATIC_ASSERT(::std::numeric_limits<T>::is_specialized || (value == 0));
+};
+
+template <class T, bool b> struct log_limit_noexcept_traits_imp : public log_limit_traits<T> {};
+template <class T> struct log_limit_noexcept_traits_imp<T, false> : public boost::integral_constant<bool, false> {};
+
+template <class T>
+struct log_limit_noexcept_traits : public log_limit_noexcept_traits_imp<T, BOOST_MATH_IS_FLOAT(T)> {};
+
} // namespace detail
#ifdef BOOST_MSVC
@@ -203,19 +214,10 @@ inline T epsilon(const mpl::false_& BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_TYPE(T))
#endif
template <class T>
-inline T log_max_value(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE(T))
+inline BOOST_MATH_CONSTEXPR T log_max_value(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE(T)) BOOST_NOEXCEPT_IF(detail::log_limit_noexcept_traits<T>::value)
{
#ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
- typedef typename mpl::if_c<
- (std::numeric_limits<T>::radix == 2) &&
- (std::numeric_limits<T>::max_exponent == 128
- || std::numeric_limits<T>::max_exponent == 1024
- || std::numeric_limits<T>::max_exponent == 16384),
- mpl::int_<(std::numeric_limits<T>::max_exponent > INT_MAX ? INT_MAX : static_cast<int>(std::numeric_limits<T>::max_exponent))>,
- mpl::int_<0>
- >::type tag_type;
- BOOST_STATIC_ASSERT( ::std::numeric_limits<T>::is_specialized);
- return detail::log_max_value<T>(tag_type());
+ return detail::log_max_value<T>(typename detail::log_limit_traits<T>::tag_type());
#else
BOOST_ASSERT(::std::numeric_limits<T>::is_specialized);
BOOST_MATH_STD_USING
@@ -225,20 +227,10 @@ inline T log_max_value(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE(T))
}
template <class T>
-inline T log_min_value(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE(T))
+inline BOOST_MATH_CONSTEXPR T log_min_value(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE(T)) BOOST_NOEXCEPT_IF(detail::log_limit_noexcept_traits<T>::value)
{
#ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
- typedef typename mpl::if_c<
- (std::numeric_limits<T>::radix == 2) &&
- (std::numeric_limits<T>::max_exponent == 128
- || std::numeric_limits<T>::max_exponent == 1024
- || std::numeric_limits<T>::max_exponent == 16384),
- mpl::int_<(std::numeric_limits<T>::max_exponent > INT_MAX ? INT_MAX : static_cast<int>(std::numeric_limits<T>::max_exponent))>,
- mpl::int_<0>
- >::type tag_type;
-
- BOOST_STATIC_ASSERT( ::std::numeric_limits<T>::is_specialized);
- return detail::log_min_value<T>(tag_type());
+ return detail::log_min_value<T>(typename detail::log_limit_traits<T>::tag_type());
#else
BOOST_ASSERT(::std::numeric_limits<T>::is_specialized);
BOOST_MATH_STD_USING
@@ -252,7 +244,7 @@ inline T log_min_value(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE(T))
#endif
template <class T>
-inline T epsilon(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC(T))
+inline BOOST_MATH_CONSTEXPR T epsilon(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC(T)) BOOST_MATH_NOEXCEPT(T)
{
#ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
return detail::epsilon<T>(mpl::bool_< ::std::numeric_limits<T>::is_specialized>());
@@ -266,25 +258,25 @@ inline T epsilon(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC(T))
namespace detail{
template <class T>
-inline T root_epsilon_imp(const mpl::int_<24>&)
+inline BOOST_MATH_CONSTEXPR T root_epsilon_imp(const mpl::int_<24>&) BOOST_MATH_NOEXCEPT(T)
{
return static_cast<T>(0.00034526698300124390839884978618400831996329879769945L);
}
template <class T>
-inline T root_epsilon_imp(const T*, const mpl::int_<53>&)
+inline BOOST_MATH_CONSTEXPR T root_epsilon_imp(const T*, const mpl::int_<53>&) BOOST_MATH_NOEXCEPT(T)
{
return static_cast<T>(0.1490116119384765625e-7L);
}
template <class T>
-inline T root_epsilon_imp(const T*, const mpl::int_<64>&)
+inline BOOST_MATH_CONSTEXPR T root_epsilon_imp(const T*, const mpl::int_<64>&) BOOST_MATH_NOEXCEPT(T)
{
return static_cast<T>(0.32927225399135962333569506281281311031656150598474e-9L);
}
template <class T>
-inline T root_epsilon_imp(const T*, const mpl::int_<113>&)
+inline BOOST_MATH_CONSTEXPR T root_epsilon_imp(const T*, const mpl::int_<113>&) BOOST_MATH_NOEXCEPT(T)
{
return static_cast<T>(0.1387778780781445675529539585113525390625e-16L);
}
@@ -298,25 +290,25 @@ inline T root_epsilon_imp(const T*, const Tag&)
}
template <class T>
-inline T cbrt_epsilon_imp(const mpl::int_<24>&)
+inline BOOST_MATH_CONSTEXPR T cbrt_epsilon_imp(const mpl::int_<24>&) BOOST_MATH_NOEXCEPT(T)
{
return static_cast<T>(0.0049215666011518482998719164346805794944150447839903L);
}
template <class T>
-inline T cbrt_epsilon_imp(const T*, const mpl::int_<53>&)
+inline BOOST_MATH_CONSTEXPR T cbrt_epsilon_imp(const T*, const mpl::int_<53>&) BOOST_MATH_NOEXCEPT(T)
{
return static_cast<T>(6.05545445239333906078989272793696693569753008995e-6L);
}
template <class T>
-inline T cbrt_epsilon_imp(const T*, const mpl::int_<64>&)
+inline BOOST_MATH_CONSTEXPR T cbrt_epsilon_imp(const T*, const mpl::int_<64>&) BOOST_MATH_NOEXCEPT(T)
{
return static_cast<T>(4.76837158203125e-7L);
}
template <class T>
-inline T cbrt_epsilon_imp(const T*, const mpl::int_<113>&)
+inline BOOST_MATH_CONSTEXPR T cbrt_epsilon_imp(const T*, const mpl::int_<113>&) BOOST_MATH_NOEXCEPT(T)
{
return static_cast<T>(5.7749313854154005630396773604745549542403508090496e-12L);
}
@@ -330,25 +322,25 @@ inline T cbrt_epsilon_imp(const T*, const Tag&)
}
template <class T>
-inline T forth_root_epsilon_imp(const T*, const mpl::int_<24>&)
+inline BOOST_MATH_CONSTEXPR T forth_root_epsilon_imp(const T*, const mpl::int_<24>&) BOOST_MATH_NOEXCEPT(T)
{
return static_cast<T>(0.018581361171917516667460937040007436176452688944747L);
}
template <class T>
-inline T forth_root_epsilon_imp(const T*, const mpl::int_<53>&)
+inline BOOST_MATH_CONSTEXPR T forth_root_epsilon_imp(const T*, const mpl::int_<53>&) BOOST_MATH_NOEXCEPT(T)
{
return static_cast<T>(0.0001220703125L);
}
template <class T>
-inline T forth_root_epsilon_imp(const T*, const mpl::int_<64>&)
+inline BOOST_MATH_CONSTEXPR T forth_root_epsilon_imp(const T*, const mpl::int_<64>&) BOOST_MATH_NOEXCEPT(T)
{
return static_cast<T>(0.18145860519450699870567321328132261891067079047605e-4L);
}
template <class T>
-inline T forth_root_epsilon_imp(const T*, const mpl::int_<113>&)
+inline BOOST_MATH_CONSTEXPR T forth_root_epsilon_imp(const T*, const mpl::int_<113>&) BOOST_MATH_NOEXCEPT(T)
{
return static_cast<T>(0.37252902984619140625e-8L);
}
@@ -361,27 +353,31 @@ inline T forth_root_epsilon_imp(const T*, const Tag&)
return r_eps;
}
+template <class T>
+struct root_epsilon_traits
+{
+ typedef mpl::int_< (::std::numeric_limits<T>::radix == 2) ? std::numeric_limits<T>::digits : 0> tag_type;
+ BOOST_STATIC_CONSTANT(bool, has_noexcept = (tag_type::value == 113) || (tag_type::value == 64) || (tag_type::value == 53) || (tag_type::value == 24));
+};
+
}
template <class T>
-inline T root_epsilon()
+inline BOOST_MATH_CONSTEXPR T root_epsilon() BOOST_NOEXCEPT_IF(BOOST_MATH_IS_FLOAT(T) && detail::root_epsilon_traits<T>::has_noexcept)
{
- typedef mpl::int_< (::std::numeric_limits<T>::radix == 2) ? std::numeric_limits<T>::digits : 0> tag_type;
- return detail::root_epsilon_imp(static_cast<T const*>(0), tag_type());
+ return detail::root_epsilon_imp(static_cast<T const*>(0), typename detail::root_epsilon_traits<T>::tag_type());
}
template <class T>
-inline T cbrt_epsilon()
+inline BOOST_MATH_CONSTEXPR T cbrt_epsilon() BOOST_NOEXCEPT_IF(BOOST_MATH_IS_FLOAT(T) && detail::root_epsilon_traits<T>::has_noexcept)
{
- typedef mpl::int_< (::std::numeric_limits<T>::radix == 2) ? std::numeric_limits<T>::digits : 0> tag_type;
- return detail::cbrt_epsilon_imp(static_cast<T const*>(0), tag_type());
+ return detail::cbrt_epsilon_imp(static_cast<T const*>(0), typename detail::root_epsilon_traits<T>::tag_type());
}
template <class T>
-inline T forth_root_epsilon()
+inline BOOST_MATH_CONSTEXPR T forth_root_epsilon() BOOST_NOEXCEPT_IF(BOOST_MATH_IS_FLOAT(T) && detail::root_epsilon_traits<T>::has_noexcept)
{
- typedef mpl::int_< (::std::numeric_limits<T>::radix == 2) ? std::numeric_limits<T>::digits : 0> tag_type;
- return detail::forth_root_epsilon_imp(static_cast<T const*>(0), tag_type());
+ return detail::forth_root_epsilon_imp(static_cast<T const*>(0), typename detail::root_epsilon_traits<T>::tag_type());
}
} // namespace tools