1 ///////////////////////////////////////////////////////////////
2 // Copyright 2012 John Maddock. Distributed under the Boost
3 // Software License, Version 1.0. (See accompanying file
4 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_
6 #ifndef BOOST_MATH_CONCEPTS_ER_HPP
7 #define BOOST_MATH_CONCEPTS_ER_HPP
13 #include <boost/cstdint.hpp>
14 #include <boost/multiprecision/number.hpp>
15 #include <boost/math/special_functions/fpclassify.hpp>
16 #include <boost/mpl/list.hpp>
19 namespace multiprecision{
24 #pragma warning(disable:4244)
27 struct number_backend_float_architype
29 typedef mpl::list<long long> signed_types;
30 typedef mpl::list<unsigned long long> unsigned_types;
31 typedef mpl::list<long double> float_types;
32 typedef int exponent_type;
34 number_backend_float_architype()
36 std::cout << "Default construct" << std::endl;
38 number_backend_float_architype(const number_backend_float_architype& o)
40 std::cout << "Copy construct" << std::endl;
43 number_backend_float_architype& operator = (const number_backend_float_architype& o)
46 std::cout << "Assignment (" << m_value << ")" << std::endl;
49 number_backend_float_architype& operator = (unsigned long long i)
52 std::cout << "UInt Assignment (" << i << ")" << std::endl;
55 number_backend_float_architype& operator = (long long i)
58 std::cout << "Int Assignment (" << i << ")" << std::endl;
61 number_backend_float_architype& operator = (long double d)
64 std::cout << "long double Assignment (" << d << ")" << std::endl;
67 number_backend_float_architype& operator = (const char* s)
71 m_value = boost::lexical_cast<long double>(s);
73 catch(const std::exception&)
75 BOOST_THROW_EXCEPTION(std::runtime_error(std::string("Unable to parse input string: \"") + s + std::string("\" as a valid floating point number.")));
77 std::cout << "const char* Assignment (" << s << ")" << std::endl;
80 void swap(number_backend_float_architype& o)
82 std::cout << "Swapping (" << m_value << " with " << o.m_value << ")" << std::endl;
83 std::swap(m_value, o.m_value);
85 std::string str(std::streamsize digits, std::ios_base::fmtflags f)const
92 ss.precision(std::numeric_limits<long double>::digits10 + 2);
93 boost::intmax_t i = m_value;
94 boost::uintmax_t u = m_value;
95 if(!(f & std::ios_base::scientific) && m_value == i)
97 else if(!(f & std::ios_base::scientific) && m_value == u)
101 std::string s = ss.str();
102 std::cout << "Converting to string (" << s << ")" << std::endl;
107 std::cout << "Negating (" << m_value << ")" << std::endl;
110 int compare(const number_backend_float_architype& o)const
112 std::cout << "Comparison" << std::endl;
113 return m_value > o.m_value ? 1 : (m_value < o.m_value ? -1 : 0);
115 int compare(long long i)const
117 std::cout << "Comparison with int" << std::endl;
118 return m_value > i ? 1 : (m_value < i ? -1 : 0);
120 int compare(unsigned long long i)const
122 std::cout << "Comparison with unsigned" << std::endl;
123 return m_value > i ? 1 : (m_value < i ? -1 : 0);
125 int compare(long double d)const
127 std::cout << "Comparison with long double" << std::endl;
128 return m_value > d ? 1 : (m_value < d ? -1 : 0);
133 inline void eval_add(number_backend_float_architype& result, const number_backend_float_architype& o)
135 std::cout << "Addition (" << result.m_value << " += " << o.m_value << ")" << std::endl;
136 result.m_value += o.m_value;
138 inline void eval_subtract(number_backend_float_architype& result, const number_backend_float_architype& o)
140 std::cout << "Subtraction (" << result.m_value << " -= " << o.m_value << ")" << std::endl;
141 result.m_value -= o.m_value;
143 inline void eval_multiply(number_backend_float_architype& result, const number_backend_float_architype& o)
145 std::cout << "Multiplication (" << result.m_value << " *= " << o.m_value << ")" << std::endl;
146 result.m_value *= o.m_value;
148 inline void eval_divide(number_backend_float_architype& result, const number_backend_float_architype& o)
150 std::cout << "Division (" << result.m_value << " /= " << o.m_value << ")" << std::endl;
151 result.m_value /= o.m_value;
154 inline void eval_convert_to(unsigned long long* result, const number_backend_float_architype& val)
156 *result = static_cast<unsigned long long>(val.m_value);
158 inline void eval_convert_to(long long* result, const number_backend_float_architype& val)
160 *result = static_cast<long long>(val.m_value);
162 inline void eval_convert_to(long double* result, number_backend_float_architype& val)
164 *result = val.m_value;
167 inline void eval_frexp(number_backend_float_architype& result, const number_backend_float_architype& arg, int* exp)
169 result = std::frexp(arg.m_value, exp);
172 inline void eval_ldexp(number_backend_float_architype& result, const number_backend_float_architype& arg, int exp)
174 result = std::ldexp(arg.m_value, exp);
177 inline void eval_floor(number_backend_float_architype& result, const number_backend_float_architype& arg)
179 result = std::floor(arg.m_value);
182 inline void eval_ceil(number_backend_float_architype& result, const number_backend_float_architype& arg)
184 result = std::ceil(arg.m_value);
187 inline void eval_sqrt(number_backend_float_architype& result, const number_backend_float_architype& arg)
189 result = std::sqrt(arg.m_value);
192 inline int eval_fpclassify(const number_backend_float_architype& arg)
194 return (boost::math::fpclassify)(arg.m_value);
197 typedef boost::multiprecision::number<number_backend_float_architype> mp_number_float_architype;
202 struct number_category<concepts::number_backend_float_architype> : public mpl::int_<number_kind_floating_point>{};
208 template <boost::multiprecision::expression_template_option ExpressionTemplates>
209 class numeric_limits<boost::multiprecision::number<boost::multiprecision::concepts::number_backend_float_architype, ExpressionTemplates> > : public std::numeric_limits<long double>
211 typedef std::numeric_limits<long double> base_type;
212 typedef boost::multiprecision::number<boost::multiprecision::concepts::number_backend_float_architype, ExpressionTemplates> number_type;
214 static number_type (min)() BOOST_NOEXCEPT { return (base_type::min)(); }
215 static number_type (max)() BOOST_NOEXCEPT { return (base_type::max)(); }
216 static number_type lowest() BOOST_NOEXCEPT { return -(max)(); }
217 static number_type epsilon() BOOST_NOEXCEPT { return base_type::epsilon(); }
218 static number_type round_error() BOOST_NOEXCEPT { return base_type::round_error(); }
219 static number_type infinity() BOOST_NOEXCEPT { return base_type::infinity(); }
220 static number_type quiet_NaN() BOOST_NOEXCEPT { return base_type::quiet_NaN(); }
221 static number_type signaling_NaN() BOOST_NOEXCEPT { return base_type::signaling_NaN(); }
222 static number_type denorm_min() BOOST_NOEXCEPT { return base_type::denorm_min(); }