Chris@16
|
1
|
Chris@16
|
2 // Copyright (c) 2011 John Maddock
|
Chris@16
|
3 // Use, modification and distribution are subject to the
|
Chris@16
|
4 // Boost Software License, Version 1.0. (See accompanying file
|
Chris@16
|
5 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
Chris@16
|
6
|
Chris@16
|
7 #ifndef BOOST_MATH_TOOLS_BIG_CONSTANT_HPP
|
Chris@16
|
8 #define BOOST_MATH_TOOLS_BIG_CONSTANT_HPP
|
Chris@16
|
9
|
Chris@16
|
10 #include <boost/math/tools/config.hpp>
|
Chris@16
|
11 #ifndef BOOST_MATH_NO_LEXICAL_CAST
|
Chris@16
|
12 #include <boost/lexical_cast.hpp>
|
Chris@16
|
13 #endif
|
Chris@16
|
14 #include <boost/type_traits/is_convertible.hpp>
|
Chris@16
|
15
|
Chris@16
|
16 namespace boost{ namespace math{
|
Chris@16
|
17
|
Chris@16
|
18 namespace tools{
|
Chris@16
|
19
|
Chris@16
|
20 template <class T>
|
Chris@101
|
21 struct numeric_traits : public std::numeric_limits< T > {};
|
Chris@101
|
22
|
Chris@101
|
23 #ifdef BOOST_MATH_USE_FLOAT128
|
Chris@101
|
24 typedef __float128 largest_float;
|
Chris@101
|
25 #define BOOST_MATH_LARGEST_FLOAT_C(x) x##Q
|
Chris@101
|
26 template <>
|
Chris@101
|
27 struct numeric_traits<__float128>
|
Chris@101
|
28 {
|
Chris@101
|
29 static const int digits = 113;
|
Chris@101
|
30 static const int digits10 = 34;
|
Chris@101
|
31 static const int max_exponent = 16384;
|
Chris@101
|
32 static const bool is_specialized = true;
|
Chris@101
|
33 };
|
Chris@101
|
34 #else
|
Chris@101
|
35 typedef long double largest_float;
|
Chris@101
|
36 #define BOOST_MATH_LARGEST_FLOAT_C(x) x##L
|
Chris@101
|
37 #endif
|
Chris@101
|
38
|
Chris@101
|
39 template <class T>
|
Chris@101
|
40 inline BOOST_CONSTEXPR_OR_CONST T make_big_value(largest_float v, const char*, mpl::true_ const&, mpl::false_ const&)
|
Chris@16
|
41 {
|
Chris@16
|
42 return static_cast<T>(v);
|
Chris@16
|
43 }
|
Chris@16
|
44 template <class T>
|
Chris@101
|
45 inline BOOST_CONSTEXPR_OR_CONST T make_big_value(largest_float v, const char*, mpl::true_ const&, mpl::true_ const&)
|
Chris@16
|
46 {
|
Chris@16
|
47 return static_cast<T>(v);
|
Chris@16
|
48 }
|
Chris@16
|
49 #ifndef BOOST_MATH_NO_LEXICAL_CAST
|
Chris@16
|
50 template <class T>
|
Chris@101
|
51 inline T make_big_value(largest_float, const char* s, mpl::false_ const&, mpl::false_ const&)
|
Chris@16
|
52 {
|
Chris@16
|
53 return boost::lexical_cast<T>(s);
|
Chris@16
|
54 }
|
Chris@16
|
55 #endif
|
Chris@16
|
56 template <class T>
|
Chris@101
|
57 inline BOOST_CONSTEXPR const char* make_big_value(largest_float, const char* s, mpl::false_ const&, mpl::true_ const&)
|
Chris@16
|
58 {
|
Chris@16
|
59 return s;
|
Chris@16
|
60 }
|
Chris@16
|
61
|
Chris@16
|
62 //
|
Chris@16
|
63 // For constants which might fit in a long double (if it's big enough):
|
Chris@16
|
64 //
|
Chris@16
|
65 #define BOOST_MATH_BIG_CONSTANT(T, D, x)\
|
Chris@16
|
66 boost::math::tools::make_big_value<T>(\
|
Chris@101
|
67 BOOST_MATH_LARGEST_FLOAT_C(x), \
|
Chris@16
|
68 BOOST_STRINGIZE(x), \
|
Chris@101
|
69 mpl::bool_< (is_convertible<boost::math::tools::largest_float, T>::value) && \
|
Chris@101
|
70 ((D <= boost::math::tools::numeric_traits<boost::math::tools::largest_float>::digits) \
|
Chris@16
|
71 || is_floating_point<T>::value \
|
Chris@101
|
72 || (boost::math::tools::numeric_traits<T>::is_specialized && \
|
Chris@101
|
73 (boost::math::tools::numeric_traits<T>::digits10 <= boost::math::tools::numeric_traits<boost::math::tools::largest_float>::digits10))) >(), \
|
Chris@16
|
74 boost::is_convertible<const char*, T>())
|
Chris@16
|
75 //
|
Chris@16
|
76 // For constants too huge for any conceivable long double (and which generate compiler errors if we try and declare them as such):
|
Chris@16
|
77 //
|
Chris@16
|
78 #define BOOST_MATH_HUGE_CONSTANT(T, D, x)\
|
Chris@16
|
79 boost::math::tools::make_big_value<T>(0.0L, BOOST_STRINGIZE(x), \
|
Chris@101
|
80 mpl::bool_<is_floating_point<T>::value || (boost::math::tools::numeric_traits<T>::is_specialized && boost::math::tools::numeric_traits<T>::max_exponent <= boost::math::tools::numeric_traits<boost::math::tools::largest_float>::max_exponent && boost::math::tools::numeric_traits<T>::digits <= boost::math::tools::numeric_traits<boost::math::tools::largest_float>::digits)>(), \
|
Chris@16
|
81 boost::is_convertible<const char*, T>())
|
Chris@16
|
82
|
Chris@16
|
83 }}} // namespaces
|
Chris@16
|
84
|
Chris@16
|
85 #endif
|
Chris@16
|
86
|