Chris@16: Chris@16: // Copyright (c) 2011 John Maddock Chris@16: // Use, modification and distribution are subject to the Chris@16: // Boost Software License, Version 1.0. (See accompanying file Chris@16: // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) Chris@16: Chris@16: #ifndef BOOST_MATH_TOOLS_BIG_CONSTANT_HPP Chris@16: #define BOOST_MATH_TOOLS_BIG_CONSTANT_HPP Chris@16: Chris@16: #include Chris@16: #ifndef BOOST_MATH_NO_LEXICAL_CAST Chris@16: #include Chris@16: #endif Chris@16: #include Chris@16: Chris@16: namespace boost{ namespace math{ Chris@16: Chris@16: namespace tools{ Chris@16: Chris@16: template Chris@101: struct numeric_traits : public std::numeric_limits< T > {}; Chris@101: Chris@101: #ifdef BOOST_MATH_USE_FLOAT128 Chris@101: typedef __float128 largest_float; Chris@101: #define BOOST_MATH_LARGEST_FLOAT_C(x) x##Q Chris@101: template <> Chris@101: struct numeric_traits<__float128> Chris@101: { Chris@101: static const int digits = 113; Chris@101: static const int digits10 = 34; Chris@101: static const int max_exponent = 16384; Chris@101: static const bool is_specialized = true; Chris@101: }; Chris@101: #else Chris@101: typedef long double largest_float; Chris@101: #define BOOST_MATH_LARGEST_FLOAT_C(x) x##L Chris@101: #endif Chris@101: Chris@101: template Chris@101: inline BOOST_CONSTEXPR_OR_CONST T make_big_value(largest_float v, const char*, mpl::true_ const&, mpl::false_ const&) Chris@16: { Chris@16: return static_cast(v); Chris@16: } Chris@16: template Chris@101: inline BOOST_CONSTEXPR_OR_CONST T make_big_value(largest_float v, const char*, mpl::true_ const&, mpl::true_ const&) Chris@16: { Chris@16: return static_cast(v); Chris@16: } Chris@16: #ifndef BOOST_MATH_NO_LEXICAL_CAST Chris@16: template Chris@101: inline T make_big_value(largest_float, const char* s, mpl::false_ const&, mpl::false_ const&) Chris@16: { Chris@16: return boost::lexical_cast(s); Chris@16: } Chris@16: #endif Chris@16: template Chris@101: inline BOOST_CONSTEXPR const char* make_big_value(largest_float, const char* s, mpl::false_ const&, mpl::true_ const&) Chris@16: { Chris@16: return s; Chris@16: } Chris@16: Chris@16: // Chris@16: // For constants which might fit in a long double (if it's big enough): Chris@16: // Chris@16: #define BOOST_MATH_BIG_CONSTANT(T, D, x)\ Chris@16: boost::math::tools::make_big_value(\ Chris@101: BOOST_MATH_LARGEST_FLOAT_C(x), \ Chris@16: BOOST_STRINGIZE(x), \ Chris@101: mpl::bool_< (is_convertible::value) && \ Chris@101: ((D <= boost::math::tools::numeric_traits::digits) \ Chris@16: || is_floating_point::value \ Chris@101: || (boost::math::tools::numeric_traits::is_specialized && \ Chris@101: (boost::math::tools::numeric_traits::digits10 <= boost::math::tools::numeric_traits::digits10))) >(), \ Chris@16: boost::is_convertible()) Chris@16: // Chris@16: // For constants too huge for any conceivable long double (and which generate compiler errors if we try and declare them as such): Chris@16: // Chris@16: #define BOOST_MATH_HUGE_CONSTANT(T, D, x)\ Chris@16: boost::math::tools::make_big_value(0.0L, BOOST_STRINGIZE(x), \ Chris@101: mpl::bool_::value || (boost::math::tools::numeric_traits::is_specialized && boost::math::tools::numeric_traits::max_exponent <= boost::math::tools::numeric_traits::max_exponent && boost::math::tools::numeric_traits::digits <= boost::math::tools::numeric_traits::digits)>(), \ Chris@16: boost::is_convertible()) Chris@16: Chris@16: }}} // namespaces Chris@16: Chris@16: #endif Chris@16: