Chris@16
|
1 ///////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
2 // Copyright 2011 John Maddock. Distributed under the Boost
|
Chris@16
|
3 // Software License, Version 1.0. (See accompanying file
|
Chris@16
|
4 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
Chris@16
|
5
|
Chris@16
|
6 #ifndef BOOST_MATH_BN_MPFI_HPP
|
Chris@16
|
7 #define BOOST_MATH_BN_MPFI_HPP
|
Chris@16
|
8
|
Chris@16
|
9 #include <boost/multiprecision/number.hpp>
|
Chris@16
|
10 #include <boost/math/special_functions/fpclassify.hpp>
|
Chris@16
|
11 #include <boost/cstdint.hpp>
|
Chris@16
|
12 #include <boost/multiprecision/detail/big_lanczos.hpp>
|
Chris@16
|
13 #include <boost/multiprecision/detail/digits.hpp>
|
Chris@16
|
14 #include <boost/multiprecision/mpfr.hpp>
|
Chris@16
|
15 #include <boost/math/constants/constants.hpp>
|
Chris@16
|
16 #include <mpfi.h>
|
Chris@16
|
17 #include <cmath>
|
Chris@16
|
18 #include <algorithm>
|
Chris@16
|
19
|
Chris@16
|
20 namespace boost{
|
Chris@16
|
21 namespace multiprecision{
|
Chris@16
|
22 namespace backends{
|
Chris@16
|
23
|
Chris@16
|
24 template <unsigned digits10>
|
Chris@16
|
25 struct mpfi_float_backend;
|
Chris@16
|
26
|
Chris@16
|
27 } // namespace backends
|
Chris@16
|
28
|
Chris@16
|
29 template <unsigned digits10>
|
Chris@16
|
30 struct number_category<backends::mpfi_float_backend<digits10> > : public mpl::int_<number_kind_floating_point>{};
|
Chris@16
|
31
|
Chris@16
|
32 struct interval_error : public std::runtime_error
|
Chris@16
|
33 {
|
Chris@16
|
34 interval_error(const std::string& s) : std::runtime_error(s) {}
|
Chris@16
|
35 };
|
Chris@16
|
36
|
Chris@16
|
37 namespace backends{
|
Chris@16
|
38
|
Chris@16
|
39 namespace detail{
|
Chris@16
|
40
|
Chris@16
|
41 inline int mpfi_sgn(mpfi_srcptr p)
|
Chris@16
|
42 {
|
Chris@16
|
43 if(mpfi_is_zero(p))
|
Chris@16
|
44 return 0;
|
Chris@16
|
45 if(mpfi_is_strictly_pos(p))
|
Chris@16
|
46 return 1;
|
Chris@16
|
47 if(mpfi_is_strictly_neg(p))
|
Chris@16
|
48 return -1;
|
Chris@16
|
49 BOOST_THROW_EXCEPTION(interval_error("Sign of interval is ambiguous."));
|
Chris@16
|
50 }
|
Chris@16
|
51
|
Chris@16
|
52 template <unsigned digits10>
|
Chris@16
|
53 struct mpfi_float_imp;
|
Chris@16
|
54
|
Chris@16
|
55 template <unsigned digits10>
|
Chris@16
|
56 struct mpfi_float_imp
|
Chris@16
|
57 {
|
Chris@16
|
58 typedef mpl::list<long, long long> signed_types;
|
Chris@16
|
59 typedef mpl::list<unsigned long, unsigned long long> unsigned_types;
|
Chris@16
|
60 typedef mpl::list<double, long double> float_types;
|
Chris@16
|
61 typedef long exponent_type;
|
Chris@16
|
62
|
Chris@16
|
63 mpfi_float_imp()
|
Chris@16
|
64 {
|
Chris@16
|
65 mpfi_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision()));
|
Chris@16
|
66 }
|
Chris@16
|
67 mpfi_float_imp(unsigned prec)
|
Chris@16
|
68 {
|
Chris@16
|
69 mpfi_init2(m_data, prec);
|
Chris@16
|
70 }
|
Chris@16
|
71
|
Chris@16
|
72 mpfi_float_imp(const mpfi_float_imp& o)
|
Chris@16
|
73 {
|
Chris@16
|
74 mpfi_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision()));
|
Chris@16
|
75 if(o.m_data[0].left._mpfr_d)
|
Chris@16
|
76 mpfi_set(m_data, o.m_data);
|
Chris@16
|
77 }
|
Chris@16
|
78 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
|
Chris@16
|
79 mpfi_float_imp(mpfi_float_imp&& o) BOOST_NOEXCEPT
|
Chris@16
|
80 {
|
Chris@16
|
81 m_data[0] = o.m_data[0];
|
Chris@16
|
82 o.m_data[0].left._mpfr_d = 0;
|
Chris@16
|
83 }
|
Chris@16
|
84 #endif
|
Chris@16
|
85 mpfi_float_imp& operator = (const mpfi_float_imp& o)
|
Chris@16
|
86 {
|
Chris@16
|
87 if(m_data[0].left._mpfr_d == 0)
|
Chris@16
|
88 mpfi_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision()));
|
Chris@16
|
89 if(o.m_data[0].left._mpfr_d)
|
Chris@16
|
90 mpfi_set(m_data, o.m_data);
|
Chris@16
|
91 return *this;
|
Chris@16
|
92 }
|
Chris@16
|
93 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
|
Chris@16
|
94 mpfi_float_imp& operator = (mpfi_float_imp&& o) BOOST_NOEXCEPT
|
Chris@16
|
95 {
|
Chris@16
|
96 mpfi_swap(m_data, o.m_data);
|
Chris@16
|
97 return *this;
|
Chris@16
|
98 }
|
Chris@16
|
99 #endif
|
Chris@16
|
100 #ifdef _MPFR_H_HAVE_INTMAX_T
|
Chris@16
|
101 mpfi_float_imp& operator = (unsigned long long i)
|
Chris@16
|
102 {
|
Chris@16
|
103 if(m_data[0].left._mpfr_d == 0)
|
Chris@16
|
104 mpfi_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision()));
|
Chris@16
|
105 mpfr_set_uj(left_data(), i, GMP_RNDD);
|
Chris@16
|
106 mpfr_set_uj(right_data(), i, GMP_RNDU);
|
Chris@16
|
107 return *this;
|
Chris@16
|
108 }
|
Chris@16
|
109 mpfi_float_imp& operator = (long long i)
|
Chris@16
|
110 {
|
Chris@16
|
111 if(m_data[0].left._mpfr_d == 0)
|
Chris@16
|
112 mpfi_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision()));
|
Chris@16
|
113 mpfr_set_sj(left_data(), i, GMP_RNDD);
|
Chris@16
|
114 mpfr_set_sj(right_data(), i, GMP_RNDU);
|
Chris@16
|
115 return *this;
|
Chris@16
|
116 }
|
Chris@16
|
117 #else
|
Chris@16
|
118 mpfi_float_imp& operator = (unsigned long long i)
|
Chris@16
|
119 {
|
Chris@16
|
120 if(m_data[0].left._mpfr_d == 0)
|
Chris@16
|
121 mpfi_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision()));
|
Chris@16
|
122 unsigned long long mask = ((1uLL << std::numeric_limits<unsigned>::digits) - 1);
|
Chris@16
|
123 unsigned shift = 0;
|
Chris@16
|
124 mpfi_t t;
|
Chris@16
|
125 mpfi_init2(t, (std::max)(static_cast<unsigned>(std::numeric_limits<unsigned long long>::digits), static_cast<unsigned>(multiprecision::detail::digits10_2_2(digits10))));
|
Chris@16
|
126 mpfi_set_ui(m_data, 0);
|
Chris@16
|
127 while(i)
|
Chris@16
|
128 {
|
Chris@16
|
129 mpfi_set_ui(t, static_cast<unsigned>(i & mask));
|
Chris@16
|
130 if(shift)
|
Chris@16
|
131 mpfi_mul_2exp(t, t, shift);
|
Chris@16
|
132 mpfi_add(m_data, m_data, t);
|
Chris@16
|
133 shift += std::numeric_limits<unsigned>::digits;
|
Chris@16
|
134 i >>= std::numeric_limits<unsigned>::digits;
|
Chris@16
|
135 }
|
Chris@16
|
136 mpfi_clear(t);
|
Chris@16
|
137 return *this;
|
Chris@16
|
138 }
|
Chris@16
|
139 mpfi_float_imp& operator = (long long i)
|
Chris@16
|
140 {
|
Chris@16
|
141 if(m_data[0].left._mpfr_d == 0)
|
Chris@16
|
142 mpfi_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision()));
|
Chris@16
|
143 bool neg = i < 0;
|
Chris@101
|
144 *this = boost::multiprecision::detail::unsigned_abs(i);
|
Chris@16
|
145 if(neg)
|
Chris@16
|
146 mpfi_neg(m_data, m_data);
|
Chris@16
|
147 return *this;
|
Chris@16
|
148 }
|
Chris@16
|
149 #endif
|
Chris@16
|
150 mpfi_float_imp& operator = (unsigned long i)
|
Chris@16
|
151 {
|
Chris@16
|
152 if(m_data[0].left._mpfr_d == 0)
|
Chris@16
|
153 mpfi_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision()));
|
Chris@16
|
154 mpfi_set_ui(m_data, i);
|
Chris@16
|
155 return *this;
|
Chris@16
|
156 }
|
Chris@16
|
157 mpfi_float_imp& operator = (long i)
|
Chris@16
|
158 {
|
Chris@16
|
159 if(m_data[0].left._mpfr_d == 0)
|
Chris@16
|
160 mpfi_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision()));
|
Chris@16
|
161 mpfi_set_si(m_data, i);
|
Chris@16
|
162 return *this;
|
Chris@16
|
163 }
|
Chris@16
|
164 mpfi_float_imp& operator = (double d)
|
Chris@16
|
165 {
|
Chris@16
|
166 if(m_data[0].left._mpfr_d == 0)
|
Chris@16
|
167 mpfi_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision()));
|
Chris@16
|
168 mpfi_set_d(m_data, d);
|
Chris@16
|
169 return *this;
|
Chris@16
|
170 }
|
Chris@16
|
171 mpfi_float_imp& operator = (long double a)
|
Chris@16
|
172 {
|
Chris@16
|
173 if(m_data[0].left._mpfr_d == 0)
|
Chris@16
|
174 mpfi_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision()));
|
Chris@16
|
175 mpfr_set_ld(left_data(), a, GMP_RNDD);
|
Chris@16
|
176 mpfr_set_ld(right_data(), a, GMP_RNDU);
|
Chris@16
|
177 return *this;
|
Chris@16
|
178 }
|
Chris@16
|
179 mpfi_float_imp& operator = (const char* s)
|
Chris@16
|
180 {
|
Chris@101
|
181 using default_ops::eval_fpclassify;
|
Chris@101
|
182
|
Chris@16
|
183 if(m_data[0].left._mpfr_d == 0)
|
Chris@16
|
184 mpfi_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision()));
|
Chris@16
|
185
|
Chris@16
|
186 if(s && (*s == '{'))
|
Chris@16
|
187 {
|
Chris@16
|
188 mpfr_float_backend<digits10> a, b;
|
Chris@16
|
189 std::string part;
|
Chris@16
|
190 const char* p = ++s;
|
Chris@16
|
191 while(*p && (*p != ',') && (*p != '}'))
|
Chris@16
|
192 ++p;
|
Chris@16
|
193 part.assign(s + 1, p);
|
Chris@16
|
194 a = part.c_str();
|
Chris@16
|
195 s = p;
|
Chris@16
|
196 if(*p && (*p != '}'))
|
Chris@16
|
197 {
|
Chris@16
|
198 ++p;
|
Chris@16
|
199 while(*p && (*p != ',') && (*p != '}'))
|
Chris@16
|
200 ++p;
|
Chris@16
|
201 part.assign(s + 1, p);
|
Chris@16
|
202 }
|
Chris@16
|
203 else
|
Chris@16
|
204 part.erase();
|
Chris@16
|
205 b = part.c_str();
|
Chris@16
|
206
|
Chris@101
|
207 if(eval_fpclassify(a) == (int)FP_NAN)
|
Chris@101
|
208 {
|
Chris@101
|
209 mpfi_set_fr(this->data(), a.data());
|
Chris@101
|
210 }
|
Chris@101
|
211 else if(eval_fpclassify(b) == (int)FP_NAN)
|
Chris@101
|
212 {
|
Chris@101
|
213 mpfi_set_fr(this->data(), b.data());
|
Chris@101
|
214 }
|
Chris@101
|
215 else
|
Chris@101
|
216 {
|
Chris@101
|
217 if(a.compare(b) > 0)
|
Chris@101
|
218 {
|
Chris@101
|
219 BOOST_THROW_EXCEPTION(std::runtime_error("Attempt to create interval with invalid range (start is greater than end)."));
|
Chris@101
|
220 }
|
Chris@101
|
221 mpfi_interv_fr(m_data, a.data(), b.data());
|
Chris@101
|
222 }
|
Chris@16
|
223 }
|
Chris@16
|
224 else if(mpfi_set_str(m_data, s, 10) != 0)
|
Chris@16
|
225 {
|
Chris@16
|
226 BOOST_THROW_EXCEPTION(std::runtime_error(std::string("Unable to parse string \"") + s + std::string("\"as a valid floating point number.")));
|
Chris@16
|
227 }
|
Chris@16
|
228 return *this;
|
Chris@16
|
229 }
|
Chris@16
|
230 void swap(mpfi_float_imp& o) BOOST_NOEXCEPT
|
Chris@16
|
231 {
|
Chris@16
|
232 mpfi_swap(m_data, o.m_data);
|
Chris@16
|
233 }
|
Chris@16
|
234 std::string str(std::streamsize digits, std::ios_base::fmtflags f)const
|
Chris@16
|
235 {
|
Chris@16
|
236 BOOST_ASSERT(m_data[0].left._mpfr_d);
|
Chris@16
|
237
|
Chris@16
|
238 mpfr_float_backend<digits10> a, b;
|
Chris@16
|
239
|
Chris@16
|
240 mpfi_get_left(a.data(), m_data);
|
Chris@16
|
241 mpfi_get_right(b.data(), m_data);
|
Chris@16
|
242
|
Chris@16
|
243 if(a.compare(b) == 0)
|
Chris@16
|
244 return a.str(digits, f);
|
Chris@16
|
245
|
Chris@16
|
246 return "{" + a.str(digits, f) + "," + b.str(digits, f) + "}";
|
Chris@16
|
247 }
|
Chris@16
|
248 ~mpfi_float_imp() BOOST_NOEXCEPT
|
Chris@16
|
249 {
|
Chris@16
|
250 if(m_data[0].left._mpfr_d)
|
Chris@16
|
251 mpfi_clear(m_data);
|
Chris@16
|
252 }
|
Chris@16
|
253 void negate() BOOST_NOEXCEPT
|
Chris@16
|
254 {
|
Chris@16
|
255 BOOST_ASSERT(m_data[0].left._mpfr_d);
|
Chris@16
|
256 mpfi_neg(m_data, m_data);
|
Chris@16
|
257 }
|
Chris@16
|
258 int compare(const mpfi_float_imp& o)const BOOST_NOEXCEPT
|
Chris@16
|
259 {
|
Chris@16
|
260 BOOST_ASSERT(m_data[0].left._mpfr_d && o.m_data[0].left._mpfr_d);
|
Chris@16
|
261 if(mpfr_cmp(right_data(), o.left_data()) < 0)
|
Chris@16
|
262 return -1;
|
Chris@16
|
263 if(mpfr_cmp(left_data(), o.right_data()) > 0)
|
Chris@16
|
264 return 1;
|
Chris@16
|
265 if((mpfr_cmp(left_data(), o.left_data()) == 0) && (mpfr_cmp(right_data(), o.right_data()) == 0))
|
Chris@16
|
266 return 0;
|
Chris@16
|
267 BOOST_THROW_EXCEPTION(interval_error("Ambiguous comparison between two values."));
|
Chris@16
|
268 return 0;
|
Chris@16
|
269 }
|
Chris@16
|
270 template <class V>
|
Chris@16
|
271 int compare(V v)const BOOST_NOEXCEPT
|
Chris@16
|
272 {
|
Chris@16
|
273 mpfi_float_imp d;
|
Chris@16
|
274 d = v;
|
Chris@16
|
275 return compare(d);
|
Chris@16
|
276 }
|
Chris@16
|
277 mpfi_t& data() BOOST_NOEXCEPT
|
Chris@16
|
278 {
|
Chris@16
|
279 BOOST_ASSERT(m_data[0].left._mpfr_d);
|
Chris@16
|
280 return m_data;
|
Chris@16
|
281 }
|
Chris@16
|
282 const mpfi_t& data()const BOOST_NOEXCEPT
|
Chris@16
|
283 {
|
Chris@16
|
284 BOOST_ASSERT(m_data[0].left._mpfr_d);
|
Chris@16
|
285 return m_data;
|
Chris@16
|
286 }
|
Chris@16
|
287 mpfr_ptr left_data() BOOST_NOEXCEPT
|
Chris@16
|
288 {
|
Chris@16
|
289 BOOST_ASSERT(m_data[0].left._mpfr_d);
|
Chris@16
|
290 return &(m_data[0].left);
|
Chris@16
|
291 }
|
Chris@16
|
292 mpfr_srcptr left_data()const BOOST_NOEXCEPT
|
Chris@16
|
293 {
|
Chris@16
|
294 BOOST_ASSERT(m_data[0].left._mpfr_d);
|
Chris@16
|
295 return &(m_data[0].left);
|
Chris@16
|
296 }
|
Chris@16
|
297 mpfr_ptr right_data() BOOST_NOEXCEPT
|
Chris@16
|
298 {
|
Chris@16
|
299 BOOST_ASSERT(m_data[0].left._mpfr_d);
|
Chris@16
|
300 return &(m_data[0].right);
|
Chris@16
|
301 }
|
Chris@16
|
302 mpfr_srcptr right_data()const BOOST_NOEXCEPT
|
Chris@16
|
303 {
|
Chris@16
|
304 BOOST_ASSERT(m_data[0].left._mpfr_d);
|
Chris@16
|
305 return &(m_data[0].right);
|
Chris@16
|
306 }
|
Chris@16
|
307 protected:
|
Chris@16
|
308 mpfi_t m_data;
|
Chris@16
|
309 static unsigned& get_default_precision() BOOST_NOEXCEPT
|
Chris@16
|
310 {
|
Chris@16
|
311 static unsigned val = 50;
|
Chris@16
|
312 return val;
|
Chris@16
|
313 }
|
Chris@16
|
314 };
|
Chris@16
|
315
|
Chris@16
|
316 } // namespace detail
|
Chris@16
|
317
|
Chris@16
|
318 template <unsigned digits10>
|
Chris@16
|
319 struct mpfi_float_backend : public detail::mpfi_float_imp<digits10>
|
Chris@16
|
320 {
|
Chris@16
|
321 mpfi_float_backend() : detail::mpfi_float_imp<digits10>() {}
|
Chris@16
|
322 mpfi_float_backend(const mpfi_float_backend& o) : detail::mpfi_float_imp<digits10>(o) {}
|
Chris@16
|
323 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
|
Chris@16
|
324 mpfi_float_backend(mpfi_float_backend&& o) : detail::mpfi_float_imp<digits10>(static_cast<detail::mpfi_float_imp<digits10>&&>(o)) {}
|
Chris@16
|
325 #endif
|
Chris@16
|
326 template <unsigned D>
|
Chris@16
|
327 mpfi_float_backend(const mpfi_float_backend<D>& val, typename enable_if_c<D <= digits10>::type* = 0)
|
Chris@16
|
328 : detail::mpfi_float_imp<digits10>()
|
Chris@16
|
329 {
|
Chris@16
|
330 mpfi_set(this->m_data, val.data());
|
Chris@16
|
331 }
|
Chris@16
|
332 template <unsigned D>
|
Chris@16
|
333 explicit mpfi_float_backend(const mpfi_float_backend<D>& val, typename disable_if_c<D <= digits10>::type* = 0)
|
Chris@16
|
334 : detail::mpfi_float_imp<digits10>()
|
Chris@16
|
335 {
|
Chris@16
|
336 mpfi_set(this->m_data, val.data());
|
Chris@16
|
337 }
|
Chris@16
|
338 mpfi_float_backend(const mpfi_t val)
|
Chris@16
|
339 : detail::mpfi_float_imp<digits10>()
|
Chris@16
|
340 {
|
Chris@16
|
341 mpfi_set(this->m_data, val);
|
Chris@16
|
342 }
|
Chris@16
|
343 mpfi_float_backend& operator=(const mpfi_float_backend& o)
|
Chris@16
|
344 {
|
Chris@16
|
345 *static_cast<detail::mpfi_float_imp<digits10>*>(this) = static_cast<detail::mpfi_float_imp<digits10> const&>(o);
|
Chris@16
|
346 return *this;
|
Chris@16
|
347 }
|
Chris@16
|
348 template <unsigned D>
|
Chris@16
|
349 mpfi_float_backend(const mpfr_float_backend<D>& val, typename enable_if_c<D <= digits10>::type* = 0)
|
Chris@16
|
350 : detail::mpfi_float_imp<digits10>()
|
Chris@16
|
351 {
|
Chris@16
|
352 mpfi_set_fr(this->m_data, val.data());
|
Chris@16
|
353 }
|
Chris@16
|
354 template <unsigned D>
|
Chris@16
|
355 mpfi_float_backend& operator=(const mpfr_float_backend<D>& val)
|
Chris@16
|
356 {
|
Chris@16
|
357 mpfi_set_fr(this->m_data, val.data());
|
Chris@16
|
358 return *this;
|
Chris@16
|
359 }
|
Chris@16
|
360 template <unsigned D>
|
Chris@16
|
361 explicit mpfi_float_backend(const mpfr_float_backend<D>& val, typename disable_if_c<D <= digits10>::type* = 0)
|
Chris@16
|
362 : detail::mpfi_float_imp<digits10>()
|
Chris@16
|
363 {
|
Chris@16
|
364 mpfi_set_fr(this->m_data, val.data());
|
Chris@16
|
365 }
|
Chris@16
|
366 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
|
Chris@16
|
367 mpfi_float_backend& operator=(mpfi_float_backend&& o) BOOST_NOEXCEPT
|
Chris@16
|
368 {
|
Chris@16
|
369 *static_cast<detail::mpfi_float_imp<digits10>*>(this) = static_cast<detail::mpfi_float_imp<digits10>&&>(o);
|
Chris@16
|
370 return *this;
|
Chris@16
|
371 }
|
Chris@16
|
372 #endif
|
Chris@16
|
373 template <class V>
|
Chris@16
|
374 mpfi_float_backend& operator=(const V& v)
|
Chris@16
|
375 {
|
Chris@16
|
376 *static_cast<detail::mpfi_float_imp<digits10>*>(this) = v;
|
Chris@16
|
377 return *this;
|
Chris@16
|
378 }
|
Chris@16
|
379 mpfi_float_backend& operator=(const mpfi_t val)
|
Chris@16
|
380 {
|
Chris@16
|
381 mpfi_set(this->m_data, val);
|
Chris@16
|
382 return *this;
|
Chris@16
|
383 }
|
Chris@16
|
384 // We don't change our precision here, this is a fixed precision type:
|
Chris@16
|
385 template <unsigned D>
|
Chris@16
|
386 mpfi_float_backend& operator=(const mpfi_float_backend<D>& val)
|
Chris@16
|
387 {
|
Chris@16
|
388 mpfi_set(this->m_data, val.data());
|
Chris@16
|
389 return *this;
|
Chris@16
|
390 }
|
Chris@16
|
391 };
|
Chris@16
|
392
|
Chris@16
|
393 template <>
|
Chris@16
|
394 struct mpfi_float_backend<0> : public detail::mpfi_float_imp<0>
|
Chris@16
|
395 {
|
Chris@16
|
396 mpfi_float_backend() : detail::mpfi_float_imp<0>() {}
|
Chris@16
|
397 mpfi_float_backend(const mpfi_t val)
|
Chris@16
|
398 : detail::mpfi_float_imp<0>(mpfi_get_prec(val))
|
Chris@16
|
399 {
|
Chris@16
|
400 mpfi_set(this->m_data, val);
|
Chris@16
|
401 }
|
Chris@16
|
402 mpfi_float_backend(const mpfi_float_backend& o) : detail::mpfi_float_imp<0>(o) {}
|
Chris@16
|
403 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
|
Chris@16
|
404 mpfi_float_backend(mpfi_float_backend&& o) BOOST_NOEXCEPT : detail::mpfi_float_imp<0>(static_cast<detail::mpfi_float_imp<0>&&>(o)) {}
|
Chris@16
|
405 #endif
|
Chris@16
|
406 mpfi_float_backend(const mpfi_float_backend& o, unsigned digits10)
|
Chris@16
|
407 : detail::mpfi_float_imp<0>(digits10)
|
Chris@16
|
408 {
|
Chris@16
|
409 *this = o;
|
Chris@16
|
410 }
|
Chris@16
|
411 template <unsigned D>
|
Chris@16
|
412 mpfi_float_backend(const mpfi_float_backend<D>& val)
|
Chris@16
|
413 : detail::mpfi_float_imp<0>(mpfi_get_prec(val.data()))
|
Chris@16
|
414 {
|
Chris@16
|
415 mpfi_set(this->m_data, val.data());
|
Chris@16
|
416 }
|
Chris@16
|
417 mpfi_float_backend& operator=(const mpfi_float_backend& o)
|
Chris@16
|
418 {
|
Chris@16
|
419 mpfi_set_prec(this->m_data, mpfi_get_prec(o.data()));
|
Chris@16
|
420 mpfi_set(this->m_data, o.data());
|
Chris@16
|
421 return *this;
|
Chris@16
|
422 }
|
Chris@16
|
423 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
|
Chris@16
|
424 mpfi_float_backend& operator=(mpfi_float_backend&& o) BOOST_NOEXCEPT
|
Chris@16
|
425 {
|
Chris@16
|
426 *static_cast<detail::mpfi_float_imp<0>*>(this) = static_cast<detail::mpfi_float_imp<0> &&>(o);
|
Chris@16
|
427 return *this;
|
Chris@16
|
428 }
|
Chris@16
|
429 #endif
|
Chris@16
|
430 template <class V>
|
Chris@16
|
431 mpfi_float_backend& operator=(const V& v)
|
Chris@16
|
432 {
|
Chris@16
|
433 *static_cast<detail::mpfi_float_imp<0>*>(this) = v;
|
Chris@16
|
434 return *this;
|
Chris@16
|
435 }
|
Chris@16
|
436 mpfi_float_backend& operator=(const mpfi_t val)
|
Chris@16
|
437 {
|
Chris@16
|
438 mpfi_set_prec(this->m_data, mpfi_get_prec(val));
|
Chris@16
|
439 mpfi_set(this->m_data, val);
|
Chris@16
|
440 return *this;
|
Chris@16
|
441 }
|
Chris@16
|
442 template <unsigned D>
|
Chris@16
|
443 mpfi_float_backend& operator=(const mpfi_float_backend<D>& val)
|
Chris@16
|
444 {
|
Chris@16
|
445 mpfi_set_prec(this->m_data, mpfi_get_prec(val.data()));
|
Chris@16
|
446 mpfi_set(this->m_data, val.data());
|
Chris@16
|
447 return *this;
|
Chris@16
|
448 }
|
Chris@16
|
449 static unsigned default_precision() BOOST_NOEXCEPT
|
Chris@16
|
450 {
|
Chris@16
|
451 return get_default_precision();
|
Chris@16
|
452 }
|
Chris@16
|
453 static void default_precision(unsigned v) BOOST_NOEXCEPT
|
Chris@16
|
454 {
|
Chris@16
|
455 get_default_precision() = v;
|
Chris@16
|
456 }
|
Chris@16
|
457 unsigned precision()const BOOST_NOEXCEPT
|
Chris@16
|
458 {
|
Chris@16
|
459 return multiprecision::detail::digits2_2_10(mpfi_get_prec(this->m_data));
|
Chris@16
|
460 }
|
Chris@16
|
461 void precision(unsigned digits10) BOOST_NOEXCEPT
|
Chris@16
|
462 {
|
Chris@16
|
463 mpfi_set_prec(this->m_data, multiprecision::detail::digits2_2_10((digits10)));
|
Chris@16
|
464 }
|
Chris@16
|
465 };
|
Chris@16
|
466
|
Chris@16
|
467 template <unsigned digits10, class T>
|
Chris@16
|
468 inline typename enable_if<is_arithmetic<T>, bool>::type eval_eq(const mpfi_float_backend<digits10>& a, const T& b) BOOST_NOEXCEPT
|
Chris@16
|
469 {
|
Chris@16
|
470 return a.compare(b) == 0;
|
Chris@16
|
471 }
|
Chris@16
|
472 template <unsigned digits10, class T>
|
Chris@16
|
473 inline typename enable_if<is_arithmetic<T>, bool>::type eval_lt(const mpfi_float_backend<digits10>& a, const T& b) BOOST_NOEXCEPT
|
Chris@16
|
474 {
|
Chris@16
|
475 return a.compare(b) < 0;
|
Chris@16
|
476 }
|
Chris@16
|
477 template <unsigned digits10, class T>
|
Chris@16
|
478 inline typename enable_if<is_arithmetic<T>, bool>::type eval_gt(const mpfi_float_backend<digits10>& a, const T& b) BOOST_NOEXCEPT
|
Chris@16
|
479 {
|
Chris@16
|
480 return a.compare(b) > 0;
|
Chris@16
|
481 }
|
Chris@16
|
482
|
Chris@16
|
483 template <unsigned D1, unsigned D2>
|
Chris@16
|
484 inline void eval_add(mpfi_float_backend<D1>& result, const mpfi_float_backend<D2>& o)
|
Chris@16
|
485 {
|
Chris@16
|
486 mpfi_add(result.data(), result.data(), o.data());
|
Chris@16
|
487 }
|
Chris@16
|
488 template <unsigned D1, unsigned D2>
|
Chris@16
|
489 inline void eval_subtract(mpfi_float_backend<D1>& result, const mpfi_float_backend<D2>& o)
|
Chris@16
|
490 {
|
Chris@16
|
491 mpfi_sub(result.data(), result.data(), o.data());
|
Chris@16
|
492 }
|
Chris@16
|
493 template <unsigned D1, unsigned D2>
|
Chris@16
|
494 inline void eval_multiply(mpfi_float_backend<D1>& result, const mpfi_float_backend<D2>& o)
|
Chris@16
|
495 {
|
Chris@16
|
496 if((void*)&result == (void*)&o)
|
Chris@16
|
497 mpfi_sqr(result.data(), o.data());
|
Chris@16
|
498 else
|
Chris@16
|
499 mpfi_mul(result.data(), result.data(), o.data());
|
Chris@16
|
500 }
|
Chris@16
|
501 template <unsigned D1, unsigned D2>
|
Chris@16
|
502 inline void eval_divide(mpfi_float_backend<D1>& result, const mpfi_float_backend<D2>& o)
|
Chris@16
|
503 {
|
Chris@16
|
504 mpfi_div(result.data(), result.data(), o.data());
|
Chris@16
|
505 }
|
Chris@16
|
506 template <unsigned digits10>
|
Chris@16
|
507 inline void eval_add(mpfi_float_backend<digits10>& result, unsigned long i)
|
Chris@16
|
508 {
|
Chris@16
|
509 mpfi_add_ui(result.data(), result.data(), i);
|
Chris@16
|
510 }
|
Chris@16
|
511 template <unsigned digits10>
|
Chris@16
|
512 inline void eval_subtract(mpfi_float_backend<digits10>& result, unsigned long i)
|
Chris@16
|
513 {
|
Chris@16
|
514 mpfi_sub_ui(result.data(), result.data(), i);
|
Chris@16
|
515 }
|
Chris@16
|
516 template <unsigned digits10>
|
Chris@16
|
517 inline void eval_multiply(mpfi_float_backend<digits10>& result, unsigned long i)
|
Chris@16
|
518 {
|
Chris@16
|
519 mpfi_mul_ui(result.data(), result.data(), i);
|
Chris@16
|
520 }
|
Chris@16
|
521 template <unsigned digits10>
|
Chris@16
|
522 inline void eval_divide(mpfi_float_backend<digits10>& result, unsigned long i)
|
Chris@16
|
523 {
|
Chris@16
|
524 mpfi_div_ui(result.data(), result.data(), i);
|
Chris@16
|
525 }
|
Chris@16
|
526 template <unsigned digits10>
|
Chris@16
|
527 inline void eval_add(mpfi_float_backend<digits10>& result, long i)
|
Chris@16
|
528 {
|
Chris@16
|
529 if(i > 0)
|
Chris@16
|
530 mpfi_add_ui(result.data(), result.data(), i);
|
Chris@16
|
531 else
|
Chris@101
|
532 mpfi_sub_ui(result.data(), result.data(), boost::multiprecision::detail::unsigned_abs(i));
|
Chris@16
|
533 }
|
Chris@16
|
534 template <unsigned digits10>
|
Chris@16
|
535 inline void eval_subtract(mpfi_float_backend<digits10>& result, long i)
|
Chris@16
|
536 {
|
Chris@16
|
537 if(i > 0)
|
Chris@16
|
538 mpfi_sub_ui(result.data(), result.data(), i);
|
Chris@16
|
539 else
|
Chris@101
|
540 mpfi_add_ui(result.data(), result.data(), boost::multiprecision::detail::unsigned_abs(i));
|
Chris@16
|
541 }
|
Chris@16
|
542 template <unsigned digits10>
|
Chris@16
|
543 inline void eval_multiply(mpfi_float_backend<digits10>& result, long i)
|
Chris@16
|
544 {
|
Chris@101
|
545 mpfi_mul_ui(result.data(), result.data(), boost::multiprecision::detail::unsigned_abs(i));
|
Chris@16
|
546 if(i < 0)
|
Chris@16
|
547 mpfi_neg(result.data(), result.data());
|
Chris@16
|
548 }
|
Chris@16
|
549 template <unsigned digits10>
|
Chris@16
|
550 inline void eval_divide(mpfi_float_backend<digits10>& result, long i)
|
Chris@16
|
551 {
|
Chris@101
|
552 mpfi_div_ui(result.data(), result.data(), boost::multiprecision::detail::unsigned_abs(i));
|
Chris@16
|
553 if(i < 0)
|
Chris@16
|
554 mpfi_neg(result.data(), result.data());
|
Chris@16
|
555 }
|
Chris@16
|
556 //
|
Chris@16
|
557 // Specialised 3 arg versions of the basic operators:
|
Chris@16
|
558 //
|
Chris@16
|
559 template <unsigned D1, unsigned D2, unsigned D3>
|
Chris@16
|
560 inline void eval_add(mpfi_float_backend<D1>& a, const mpfi_float_backend<D2>& x, const mpfi_float_backend<D3>& y)
|
Chris@16
|
561 {
|
Chris@16
|
562 mpfi_add(a.data(), x.data(), y.data());
|
Chris@16
|
563 }
|
Chris@16
|
564 template <unsigned D1, unsigned D2>
|
Chris@16
|
565 inline void eval_add(mpfi_float_backend<D1>& a, const mpfi_float_backend<D2>& x, unsigned long y)
|
Chris@16
|
566 {
|
Chris@16
|
567 mpfi_add_ui(a.data(), x.data(), y);
|
Chris@16
|
568 }
|
Chris@16
|
569 template <unsigned D1, unsigned D2>
|
Chris@16
|
570 inline void eval_add(mpfi_float_backend<D1>& a, const mpfi_float_backend<D2>& x, long y)
|
Chris@16
|
571 {
|
Chris@16
|
572 if(y < 0)
|
Chris@101
|
573 mpfi_sub_ui(a.data(), x.data(), boost::multiprecision::detail::unsigned_abs(y));
|
Chris@16
|
574 else
|
Chris@16
|
575 mpfi_add_ui(a.data(), x.data(), y);
|
Chris@16
|
576 }
|
Chris@16
|
577 template <unsigned D1, unsigned D2>
|
Chris@16
|
578 inline void eval_add(mpfi_float_backend<D1>& a, unsigned long x, const mpfi_float_backend<D2>& y)
|
Chris@16
|
579 {
|
Chris@16
|
580 mpfi_add_ui(a.data(), y.data(), x);
|
Chris@16
|
581 }
|
Chris@16
|
582 template <unsigned D1, unsigned D2>
|
Chris@16
|
583 inline void eval_add(mpfi_float_backend<D1>& a, long x, const mpfi_float_backend<D2>& y)
|
Chris@16
|
584 {
|
Chris@16
|
585 if(x < 0)
|
Chris@16
|
586 {
|
Chris@101
|
587 mpfi_ui_sub(a.data(), boost::multiprecision::detail::unsigned_abs(x), y.data());
|
Chris@16
|
588 mpfi_neg(a.data(), a.data());
|
Chris@16
|
589 }
|
Chris@16
|
590 else
|
Chris@16
|
591 mpfi_add_ui(a.data(), y.data(), x);
|
Chris@16
|
592 }
|
Chris@16
|
593 template <unsigned D1, unsigned D2, unsigned D3>
|
Chris@16
|
594 inline void eval_subtract(mpfi_float_backend<D1>& a, const mpfi_float_backend<D2>& x, const mpfi_float_backend<D3>& y)
|
Chris@16
|
595 {
|
Chris@16
|
596 mpfi_sub(a.data(), x.data(), y.data());
|
Chris@16
|
597 }
|
Chris@16
|
598 template <unsigned D1, unsigned D2>
|
Chris@16
|
599 inline void eval_subtract(mpfi_float_backend<D1>& a, const mpfi_float_backend<D2>& x, unsigned long y)
|
Chris@16
|
600 {
|
Chris@16
|
601 mpfi_sub_ui(a.data(), x.data(), y);
|
Chris@16
|
602 }
|
Chris@16
|
603 template <unsigned D1, unsigned D2>
|
Chris@16
|
604 inline void eval_subtract(mpfi_float_backend<D1>& a, const mpfi_float_backend<D2>& x, long y)
|
Chris@16
|
605 {
|
Chris@16
|
606 if(y < 0)
|
Chris@101
|
607 mpfi_add_ui(a.data(), x.data(), boost::multiprecision::detail::unsigned_abs(y));
|
Chris@16
|
608 else
|
Chris@16
|
609 mpfi_sub_ui(a.data(), x.data(), y);
|
Chris@16
|
610 }
|
Chris@16
|
611 template <unsigned D1, unsigned D2>
|
Chris@16
|
612 inline void eval_subtract(mpfi_float_backend<D1>& a, unsigned long x, const mpfi_float_backend<D2>& y)
|
Chris@16
|
613 {
|
Chris@16
|
614 mpfi_ui_sub(a.data(), x, y.data());
|
Chris@16
|
615 }
|
Chris@16
|
616 template <unsigned D1, unsigned D2>
|
Chris@16
|
617 inline void eval_subtract(mpfi_float_backend<D1>& a, long x, const mpfi_float_backend<D2>& y)
|
Chris@16
|
618 {
|
Chris@16
|
619 if(x < 0)
|
Chris@16
|
620 {
|
Chris@101
|
621 mpfi_add_ui(a.data(), y.data(), boost::multiprecision::detail::unsigned_abs(x));
|
Chris@16
|
622 mpfi_neg(a.data(), a.data());
|
Chris@16
|
623 }
|
Chris@16
|
624 else
|
Chris@16
|
625 mpfi_ui_sub(a.data(), x, y.data());
|
Chris@16
|
626 }
|
Chris@16
|
627
|
Chris@16
|
628 template <unsigned D1, unsigned D2, unsigned D3>
|
Chris@16
|
629 inline void eval_multiply(mpfi_float_backend<D1>& a, const mpfi_float_backend<D2>& x, const mpfi_float_backend<D3>& y)
|
Chris@16
|
630 {
|
Chris@16
|
631 if((void*)&x == (void*)&y)
|
Chris@16
|
632 mpfi_sqr(a.data(), x.data());
|
Chris@16
|
633 else
|
Chris@16
|
634 mpfi_mul(a.data(), x.data(), y.data());
|
Chris@16
|
635 }
|
Chris@16
|
636 template <unsigned D1, unsigned D2>
|
Chris@16
|
637 inline void eval_multiply(mpfi_float_backend<D1>& a, const mpfi_float_backend<D2>& x, unsigned long y)
|
Chris@16
|
638 {
|
Chris@16
|
639 mpfi_mul_ui(a.data(), x.data(), y);
|
Chris@16
|
640 }
|
Chris@16
|
641 template <unsigned D1, unsigned D2>
|
Chris@16
|
642 inline void eval_multiply(mpfi_float_backend<D1>& a, const mpfi_float_backend<D2>& x, long y)
|
Chris@16
|
643 {
|
Chris@16
|
644 if(y < 0)
|
Chris@16
|
645 {
|
Chris@101
|
646 mpfi_mul_ui(a.data(), x.data(), boost::multiprecision::detail::unsigned_abs(y));
|
Chris@16
|
647 a.negate();
|
Chris@16
|
648 }
|
Chris@16
|
649 else
|
Chris@16
|
650 mpfi_mul_ui(a.data(), x.data(), y);
|
Chris@16
|
651 }
|
Chris@16
|
652 template <unsigned D1, unsigned D2>
|
Chris@16
|
653 inline void eval_multiply(mpfi_float_backend<D1>& a, unsigned long x, const mpfi_float_backend<D2>& y)
|
Chris@16
|
654 {
|
Chris@16
|
655 mpfi_mul_ui(a.data(), y.data(), x);
|
Chris@16
|
656 }
|
Chris@16
|
657 template <unsigned D1, unsigned D2>
|
Chris@16
|
658 inline void eval_multiply(mpfi_float_backend<D1>& a, long x, const mpfi_float_backend<D2>& y)
|
Chris@16
|
659 {
|
Chris@16
|
660 if(x < 0)
|
Chris@16
|
661 {
|
Chris@101
|
662 mpfi_mul_ui(a.data(), y.data(), boost::multiprecision::detail::unsigned_abs(x));
|
Chris@16
|
663 mpfi_neg(a.data(), a.data());
|
Chris@16
|
664 }
|
Chris@16
|
665 else
|
Chris@16
|
666 mpfi_mul_ui(a.data(), y.data(), x);
|
Chris@16
|
667 }
|
Chris@16
|
668
|
Chris@16
|
669 template <unsigned D1, unsigned D2, unsigned D3>
|
Chris@16
|
670 inline void eval_divide(mpfi_float_backend<D1>& a, const mpfi_float_backend<D2>& x, const mpfi_float_backend<D3>& y)
|
Chris@16
|
671 {
|
Chris@16
|
672 mpfi_div(a.data(), x.data(), y.data());
|
Chris@16
|
673 }
|
Chris@16
|
674 template <unsigned D1, unsigned D2>
|
Chris@16
|
675 inline void eval_divide(mpfi_float_backend<D1>& a, const mpfi_float_backend<D2>& x, unsigned long y)
|
Chris@16
|
676 {
|
Chris@16
|
677 mpfi_div_ui(a.data(), x.data(), y);
|
Chris@16
|
678 }
|
Chris@16
|
679 template <unsigned D1, unsigned D2>
|
Chris@16
|
680 inline void eval_divide(mpfi_float_backend<D1>& a, const mpfi_float_backend<D2>& x, long y)
|
Chris@16
|
681 {
|
Chris@16
|
682 if(y < 0)
|
Chris@16
|
683 {
|
Chris@101
|
684 mpfi_div_ui(a.data(), x.data(), boost::multiprecision::detail::unsigned_abs(y));
|
Chris@16
|
685 a.negate();
|
Chris@16
|
686 }
|
Chris@16
|
687 else
|
Chris@16
|
688 mpfi_div_ui(a.data(), x.data(), y);
|
Chris@16
|
689 }
|
Chris@16
|
690 template <unsigned D1, unsigned D2>
|
Chris@16
|
691 inline void eval_divide(mpfi_float_backend<D1>& a, unsigned long x, const mpfi_float_backend<D2>& y)
|
Chris@16
|
692 {
|
Chris@16
|
693 mpfi_ui_div(a.data(), x, y.data());
|
Chris@16
|
694 }
|
Chris@16
|
695 template <unsigned D1, unsigned D2>
|
Chris@16
|
696 inline void eval_divide(mpfi_float_backend<D1>& a, long x, const mpfi_float_backend<D2>& y)
|
Chris@16
|
697 {
|
Chris@16
|
698 if(x < 0)
|
Chris@16
|
699 {
|
Chris@101
|
700 mpfi_ui_div(a.data(), boost::multiprecision::detail::unsigned_abs(x), y.data());
|
Chris@16
|
701 mpfi_neg(a.data(), a.data());
|
Chris@16
|
702 }
|
Chris@16
|
703 else
|
Chris@16
|
704 mpfi_ui_div(a.data(), x, y.data());
|
Chris@16
|
705 }
|
Chris@16
|
706
|
Chris@16
|
707 template <unsigned digits10>
|
Chris@16
|
708 inline bool eval_is_zero(const mpfi_float_backend<digits10>& val) BOOST_NOEXCEPT
|
Chris@16
|
709 {
|
Chris@16
|
710 return 0 != mpfi_is_zero(val.data());
|
Chris@16
|
711 }
|
Chris@16
|
712 template <unsigned digits10>
|
Chris@16
|
713 inline int eval_get_sign(const mpfi_float_backend<digits10>& val)
|
Chris@16
|
714 {
|
Chris@16
|
715 return detail::mpfi_sgn(val.data());
|
Chris@16
|
716 }
|
Chris@16
|
717
|
Chris@16
|
718 template <unsigned digits10>
|
Chris@16
|
719 inline void eval_convert_to(unsigned long* result, const mpfi_float_backend<digits10>& val)
|
Chris@16
|
720 {
|
Chris@16
|
721 mpfr_float_backend<digits10> t;
|
Chris@16
|
722 mpfi_mid(t.data(), val.data());
|
Chris@16
|
723 eval_convert_to(result, t);
|
Chris@16
|
724 }
|
Chris@16
|
725 template <unsigned digits10>
|
Chris@16
|
726 inline void eval_convert_to(long* result, const mpfi_float_backend<digits10>& val)
|
Chris@16
|
727 {
|
Chris@16
|
728 mpfr_float_backend<digits10> t;
|
Chris@16
|
729 mpfi_mid(t.data(), val.data());
|
Chris@16
|
730 eval_convert_to(result, t);
|
Chris@16
|
731 }
|
Chris@16
|
732 #ifdef _MPFR_H_HAVE_INTMAX_T
|
Chris@16
|
733 template <unsigned digits10>
|
Chris@16
|
734 inline void eval_convert_to(unsigned long long* result, const mpfi_float_backend<digits10>& val)
|
Chris@16
|
735 {
|
Chris@16
|
736 mpfr_float_backend<digits10> t;
|
Chris@16
|
737 mpfi_mid(t.data(), val.data());
|
Chris@16
|
738 eval_convert_to(result, t);
|
Chris@16
|
739 }
|
Chris@16
|
740 template <unsigned digits10>
|
Chris@16
|
741 inline void eval_convert_to(long long* result, const mpfi_float_backend<digits10>& val)
|
Chris@16
|
742 {
|
Chris@16
|
743 mpfr_float_backend<digits10> t;
|
Chris@16
|
744 mpfi_mid(t.data(), val.data());
|
Chris@16
|
745 eval_convert_to(result, t);
|
Chris@16
|
746 }
|
Chris@16
|
747 #endif
|
Chris@16
|
748 template <unsigned digits10>
|
Chris@16
|
749 inline void eval_convert_to(double* result, const mpfi_float_backend<digits10>& val) BOOST_NOEXCEPT
|
Chris@16
|
750 {
|
Chris@16
|
751 *result = mpfi_get_d(val.data());
|
Chris@16
|
752 }
|
Chris@16
|
753 template <unsigned digits10>
|
Chris@16
|
754 inline void eval_convert_to(long double* result, const mpfi_float_backend<digits10>& val) BOOST_NOEXCEPT
|
Chris@16
|
755 {
|
Chris@16
|
756 mpfr_float_backend<digits10> t;
|
Chris@16
|
757 mpfi_mid(t.data(), val.data());
|
Chris@16
|
758 eval_convert_to(result, t);
|
Chris@16
|
759 }
|
Chris@16
|
760
|
Chris@16
|
761 template <unsigned D1, unsigned D2, mpfr_allocation_type AllocationType>
|
Chris@16
|
762 inline void assign_components(mpfi_float_backend<D1>& result, const mpfr_float_backend<D2, AllocationType>& a, const mpfr_float_backend<D2, AllocationType>& b)
|
Chris@16
|
763 {
|
Chris@101
|
764 using default_ops::eval_fpclassify;
|
Chris@101
|
765 if(eval_fpclassify(a) == (int)FP_NAN)
|
Chris@101
|
766 {
|
Chris@101
|
767 mpfi_set_fr(result.data(), a.data());
|
Chris@101
|
768 }
|
Chris@101
|
769 else if(eval_fpclassify(b) == (int)FP_NAN)
|
Chris@101
|
770 {
|
Chris@101
|
771 mpfi_set_fr(result.data(), b.data());
|
Chris@101
|
772 }
|
Chris@101
|
773 else
|
Chris@101
|
774 {
|
Chris@101
|
775 if(a.compare(b) > 0)
|
Chris@101
|
776 {
|
Chris@101
|
777 BOOST_THROW_EXCEPTION(std::runtime_error("Attempt to create interval with invalid range (start is greater than end)."));
|
Chris@101
|
778 }
|
Chris@101
|
779 mpfi_interv_fr(result.data(), a.data(), b.data());
|
Chris@101
|
780 }
|
Chris@16
|
781 }
|
Chris@16
|
782
|
Chris@16
|
783 template <unsigned Digits10, class V>
|
Chris@16
|
784 inline typename enable_if_c<is_convertible<V, number<mpfr_float_backend<Digits10, allocate_dynamic>, et_on> >::value >::type
|
Chris@16
|
785 assign_components(mpfi_float_backend<Digits10>& result, const V& a, const V& b)
|
Chris@16
|
786 {
|
Chris@16
|
787 number<mpfr_float_backend<Digits10, allocate_dynamic>, et_on> x(a), y(b);
|
Chris@16
|
788 assign_components(result, x.backend(), y.backend());
|
Chris@16
|
789 }
|
Chris@16
|
790
|
Chris@16
|
791 //
|
Chris@16
|
792 // Native non-member operations:
|
Chris@16
|
793 //
|
Chris@16
|
794 template <unsigned Digits10>
|
Chris@16
|
795 inline void eval_sqrt(mpfi_float_backend<Digits10>& result, const mpfi_float_backend<Digits10>& val)
|
Chris@16
|
796 {
|
Chris@16
|
797 mpfi_sqrt(result.data(), val.data());
|
Chris@16
|
798 }
|
Chris@16
|
799
|
Chris@16
|
800 template <unsigned Digits10>
|
Chris@16
|
801 inline void eval_abs(mpfi_float_backend<Digits10>& result, const mpfi_float_backend<Digits10>& val)
|
Chris@16
|
802 {
|
Chris@16
|
803 mpfi_abs(result.data(), val.data());
|
Chris@16
|
804 }
|
Chris@16
|
805
|
Chris@16
|
806 template <unsigned Digits10>
|
Chris@16
|
807 inline void eval_fabs(mpfi_float_backend<Digits10>& result, const mpfi_float_backend<Digits10>& val)
|
Chris@16
|
808 {
|
Chris@16
|
809 mpfi_abs(result.data(), val.data());
|
Chris@16
|
810 }
|
Chris@16
|
811 template <unsigned Digits10>
|
Chris@16
|
812 inline void eval_ceil(mpfi_float_backend<Digits10>& result, const mpfi_float_backend<Digits10>& val)
|
Chris@16
|
813 {
|
Chris@16
|
814 mpfr_float_backend<Digits10> a, b;
|
Chris@16
|
815 mpfr_set(a.data(), val.left_data(), GMP_RNDN);
|
Chris@16
|
816 mpfr_set(b.data(), val.right_data(), GMP_RNDN);
|
Chris@16
|
817 eval_ceil(a, a);
|
Chris@16
|
818 eval_ceil(b, b);
|
Chris@16
|
819 if(a.compare(b) != 0)
|
Chris@16
|
820 {
|
Chris@16
|
821 BOOST_THROW_EXCEPTION(interval_error("Attempt to take the ceil of a value that straddles an integer boundary."));
|
Chris@16
|
822 }
|
Chris@16
|
823 mpfi_set_fr(result.data(), a.data());
|
Chris@16
|
824 }
|
Chris@16
|
825 template <unsigned Digits10>
|
Chris@16
|
826 inline void eval_floor(mpfi_float_backend<Digits10>& result, const mpfi_float_backend<Digits10>& val)
|
Chris@16
|
827 {
|
Chris@16
|
828 mpfr_float_backend<Digits10> a, b;
|
Chris@16
|
829 mpfr_set(a.data(), val.left_data(), GMP_RNDN);
|
Chris@16
|
830 mpfr_set(b.data(), val.right_data(), GMP_RNDN);
|
Chris@16
|
831 eval_floor(a, a);
|
Chris@16
|
832 eval_floor(b, b);
|
Chris@16
|
833 if(a.compare(b) != 0)
|
Chris@16
|
834 {
|
Chris@16
|
835 BOOST_THROW_EXCEPTION(interval_error("Attempt to take the floor of a value that straddles an integer boundary."));
|
Chris@16
|
836 }
|
Chris@16
|
837 mpfi_set_fr(result.data(), a.data());
|
Chris@16
|
838 }
|
Chris@16
|
839 template <unsigned Digits10>
|
Chris@16
|
840 inline void eval_ldexp(mpfi_float_backend<Digits10>& result, const mpfi_float_backend<Digits10>& val, long e)
|
Chris@16
|
841 {
|
Chris@16
|
842 if(e > 0)
|
Chris@16
|
843 mpfi_mul_2exp(result.data(), val.data(), e);
|
Chris@16
|
844 else if(e < 0)
|
Chris@16
|
845 mpfi_div_2exp(result.data(), val.data(), -e);
|
Chris@16
|
846 else
|
Chris@16
|
847 result = val;
|
Chris@16
|
848 }
|
Chris@16
|
849 template <unsigned Digits10>
|
Chris@16
|
850 inline void eval_frexp(mpfi_float_backend<Digits10>& result, const mpfi_float_backend<Digits10>& val, int* e)
|
Chris@16
|
851 {
|
Chris@16
|
852 mpfr_float_backend<Digits10> t, rt;
|
Chris@16
|
853 mpfi_mid(t.data(), val.data());
|
Chris@16
|
854 eval_frexp(rt, t, e);
|
Chris@16
|
855 eval_ldexp(result, val, -*e);
|
Chris@16
|
856 }
|
Chris@16
|
857 template <unsigned Digits10>
|
Chris@16
|
858 inline void eval_frexp(mpfi_float_backend<Digits10>& result, const mpfi_float_backend<Digits10>& val, long* e)
|
Chris@16
|
859 {
|
Chris@16
|
860 mpfr_float_backend<Digits10> t, rt;
|
Chris@16
|
861 mpfi_mid(t.data(), val.data());
|
Chris@16
|
862 eval_frexp(rt, t, e);
|
Chris@16
|
863 eval_ldexp(result, val, -*e);
|
Chris@16
|
864 }
|
Chris@16
|
865
|
Chris@16
|
866 template <unsigned Digits10>
|
Chris@16
|
867 inline int eval_fpclassify(const mpfi_float_backend<Digits10>& val) BOOST_NOEXCEPT
|
Chris@16
|
868 {
|
Chris@16
|
869 return mpfi_inf_p(val.data()) ? FP_INFINITE : mpfi_nan_p(val.data()) ? FP_NAN : mpfi_is_zero(val.data()) ? FP_ZERO : FP_NORMAL;
|
Chris@16
|
870 }
|
Chris@16
|
871
|
Chris@16
|
872 template <unsigned Digits10>
|
Chris@16
|
873 inline void eval_pow(mpfi_float_backend<Digits10>& result, const mpfi_float_backend<Digits10>& b, const mpfi_float_backend<Digits10>& e)
|
Chris@16
|
874 {
|
Chris@16
|
875 typedef typename boost::multiprecision::detail::canonical<unsigned, mpfi_float_backend<Digits10> >::type ui_type;
|
Chris@16
|
876 using default_ops::eval_get_sign;
|
Chris@16
|
877 int s = eval_get_sign(b);
|
Chris@16
|
878 if(s == 0)
|
Chris@16
|
879 {
|
Chris@16
|
880 if(eval_get_sign(e) == 0)
|
Chris@16
|
881 {
|
Chris@16
|
882 result = ui_type(1);
|
Chris@16
|
883 }
|
Chris@16
|
884 else
|
Chris@16
|
885 {
|
Chris@16
|
886 result = ui_type(0);
|
Chris@16
|
887 }
|
Chris@16
|
888 return;
|
Chris@16
|
889 }
|
Chris@16
|
890 if(s < 0)
|
Chris@16
|
891 {
|
Chris@16
|
892 if(eval_get_sign(e) < 0)
|
Chris@16
|
893 {
|
Chris@16
|
894 mpfi_float_backend<Digits10> t1, t2;
|
Chris@16
|
895 t1 = e;
|
Chris@16
|
896 t1.negate();
|
Chris@16
|
897 eval_pow(t2, b, t1);
|
Chris@16
|
898 t1 = ui_type(1);
|
Chris@16
|
899 eval_divide(result, t1, t2);
|
Chris@16
|
900 return;
|
Chris@16
|
901 }
|
Chris@16
|
902 typename boost::multiprecision::detail::canonical<boost::uintmax_t, mpfi_float_backend<Digits10> >::type an;
|
Chris@16
|
903 try
|
Chris@16
|
904 {
|
Chris@16
|
905 using default_ops::eval_convert_to;
|
Chris@16
|
906 eval_convert_to(&an, e);
|
Chris@16
|
907 if(e.compare(an) == 0)
|
Chris@16
|
908 {
|
Chris@16
|
909 mpfi_float_backend<Digits10> pb(b);
|
Chris@16
|
910 pb.negate();
|
Chris@16
|
911 eval_pow(result, pb, e);
|
Chris@16
|
912 if(an & 1u)
|
Chris@16
|
913 result.negate();
|
Chris@16
|
914 return;
|
Chris@16
|
915 }
|
Chris@16
|
916 }
|
Chris@16
|
917 catch(const std::exception&)
|
Chris@16
|
918 {
|
Chris@16
|
919 // conversion failed, just fall through, value is not an integer.
|
Chris@16
|
920 }
|
Chris@16
|
921 result = std::numeric_limits<number<mpfi_float_backend<Digits10>, et_on> >::quiet_NaN().backend();
|
Chris@16
|
922 return;
|
Chris@16
|
923 }
|
Chris@16
|
924 mpfi_log(result.data(), b.data());
|
Chris@16
|
925 mpfi_mul(result.data(), result.data(), e.data());
|
Chris@16
|
926 mpfi_exp(result.data(), result.data());
|
Chris@16
|
927 }
|
Chris@16
|
928
|
Chris@16
|
929 template <unsigned Digits10>
|
Chris@16
|
930 inline void eval_exp(mpfi_float_backend<Digits10>& result, const mpfi_float_backend<Digits10>& arg)
|
Chris@16
|
931 {
|
Chris@16
|
932 mpfi_exp(result.data(), arg.data());
|
Chris@16
|
933 }
|
Chris@16
|
934
|
Chris@16
|
935 template <unsigned Digits10>
|
Chris@16
|
936 inline void eval_log(mpfi_float_backend<Digits10>& result, const mpfi_float_backend<Digits10>& arg)
|
Chris@16
|
937 {
|
Chris@16
|
938 mpfi_log(result.data(), arg.data());
|
Chris@16
|
939 }
|
Chris@16
|
940
|
Chris@16
|
941 template <unsigned Digits10>
|
Chris@16
|
942 inline void eval_log10(mpfi_float_backend<Digits10>& result, const mpfi_float_backend<Digits10>& arg)
|
Chris@16
|
943 {
|
Chris@16
|
944 mpfi_log10(result.data(), arg.data());
|
Chris@16
|
945 }
|
Chris@16
|
946
|
Chris@16
|
947 template <unsigned Digits10>
|
Chris@16
|
948 inline void eval_sin(mpfi_float_backend<Digits10>& result, const mpfi_float_backend<Digits10>& arg)
|
Chris@16
|
949 {
|
Chris@16
|
950 mpfi_sin(result.data(), arg.data());
|
Chris@16
|
951 }
|
Chris@16
|
952
|
Chris@16
|
953 template <unsigned Digits10>
|
Chris@16
|
954 inline void eval_cos(mpfi_float_backend<Digits10>& result, const mpfi_float_backend<Digits10>& arg)
|
Chris@16
|
955 {
|
Chris@16
|
956 mpfi_cos(result.data(), arg.data());
|
Chris@16
|
957 }
|
Chris@16
|
958
|
Chris@16
|
959 template <unsigned Digits10>
|
Chris@16
|
960 inline void eval_tan(mpfi_float_backend<Digits10>& result, const mpfi_float_backend<Digits10>& arg)
|
Chris@16
|
961 {
|
Chris@16
|
962 mpfi_tan(result.data(), arg.data());
|
Chris@16
|
963 }
|
Chris@16
|
964
|
Chris@16
|
965 template <unsigned Digits10>
|
Chris@16
|
966 inline void eval_asin(mpfi_float_backend<Digits10>& result, const mpfi_float_backend<Digits10>& arg)
|
Chris@16
|
967 {
|
Chris@16
|
968 mpfi_asin(result.data(), arg.data());
|
Chris@16
|
969 }
|
Chris@16
|
970
|
Chris@16
|
971 template <unsigned Digits10>
|
Chris@16
|
972 inline void eval_acos(mpfi_float_backend<Digits10>& result, const mpfi_float_backend<Digits10>& arg)
|
Chris@16
|
973 {
|
Chris@16
|
974 mpfi_acos(result.data(), arg.data());
|
Chris@16
|
975 }
|
Chris@16
|
976
|
Chris@16
|
977 template <unsigned Digits10>
|
Chris@16
|
978 inline void eval_atan(mpfi_float_backend<Digits10>& result, const mpfi_float_backend<Digits10>& arg)
|
Chris@16
|
979 {
|
Chris@16
|
980 mpfi_atan(result.data(), arg.data());
|
Chris@16
|
981 }
|
Chris@16
|
982
|
Chris@16
|
983 template <unsigned Digits10>
|
Chris@16
|
984 inline void eval_atan2(mpfi_float_backend<Digits10>& result, const mpfi_float_backend<Digits10>& arg1, const mpfi_float_backend<Digits10>& arg2)
|
Chris@16
|
985 {
|
Chris@16
|
986 mpfi_atan2(result.data(), arg1.data(), arg2.data());
|
Chris@16
|
987 }
|
Chris@16
|
988
|
Chris@16
|
989 template <unsigned Digits10>
|
Chris@16
|
990 inline void eval_sinh(mpfi_float_backend<Digits10>& result, const mpfi_float_backend<Digits10>& arg)
|
Chris@16
|
991 {
|
Chris@16
|
992 mpfi_sinh(result.data(), arg.data());
|
Chris@16
|
993 }
|
Chris@16
|
994
|
Chris@16
|
995 template <unsigned Digits10>
|
Chris@16
|
996 inline void eval_cosh(mpfi_float_backend<Digits10>& result, const mpfi_float_backend<Digits10>& arg)
|
Chris@16
|
997 {
|
Chris@16
|
998 mpfi_cosh(result.data(), arg.data());
|
Chris@16
|
999 }
|
Chris@16
|
1000
|
Chris@16
|
1001 template <unsigned Digits10>
|
Chris@16
|
1002 inline void eval_tanh(mpfi_float_backend<Digits10>& result, const mpfi_float_backend<Digits10>& arg)
|
Chris@16
|
1003 {
|
Chris@16
|
1004 mpfi_tanh(result.data(), arg.data());
|
Chris@16
|
1005 }
|
Chris@16
|
1006
|
Chris@16
|
1007 } // namespace backends
|
Chris@16
|
1008
|
Chris@16
|
1009 #ifdef BOOST_NO_SFINAE_EXPR
|
Chris@16
|
1010
|
Chris@16
|
1011 namespace detail{
|
Chris@16
|
1012
|
Chris@16
|
1013 template<unsigned D1, unsigned D2>
|
Chris@16
|
1014 struct is_explicitly_convertible<backends::mpfi_float_backend<D1>, backends::mpfi_float_backend<D2> > : public mpl::true_ {};
|
Chris@16
|
1015
|
Chris@16
|
1016 }
|
Chris@16
|
1017
|
Chris@16
|
1018 #endif
|
Chris@16
|
1019
|
Chris@16
|
1020 template<>
|
Chris@16
|
1021 struct number_category<detail::canonical<mpfi_t, backends::mpfi_float_backend<0> >::type> : public mpl::int_<number_kind_floating_point>{};
|
Chris@16
|
1022 template <unsigned Digits10>
|
Chris@16
|
1023 struct is_interval_number<backends::mpfi_float_backend<Digits10> > : public mpl::true_ {};
|
Chris@16
|
1024
|
Chris@16
|
1025 using boost::multiprecision::backends::mpfi_float_backend;
|
Chris@16
|
1026
|
Chris@16
|
1027 typedef number<mpfi_float_backend<50> > mpfi_float_50;
|
Chris@16
|
1028 typedef number<mpfi_float_backend<100> > mpfi_float_100;
|
Chris@16
|
1029 typedef number<mpfi_float_backend<500> > mpfi_float_500;
|
Chris@16
|
1030 typedef number<mpfi_float_backend<1000> > mpfi_float_1000;
|
Chris@16
|
1031 typedef number<mpfi_float_backend<0> > mpfi_float;
|
Chris@16
|
1032
|
Chris@16
|
1033 //
|
Chris@16
|
1034 // Special interval specific functions:
|
Chris@16
|
1035 //
|
Chris@16
|
1036 template <unsigned Digits10, expression_template_option ExpressionTemplates>
|
Chris@16
|
1037 inline number<mpfr_float_backend<Digits10>, ExpressionTemplates> lower(const number<mpfi_float_backend<Digits10>, ExpressionTemplates>& val)
|
Chris@16
|
1038 {
|
Chris@16
|
1039 number<mpfr_float_backend<Digits10> > result;
|
Chris@16
|
1040 mpfr_set(result.backend().data(), val.backend().left_data(), GMP_RNDN);
|
Chris@16
|
1041 return result;
|
Chris@16
|
1042 }
|
Chris@16
|
1043
|
Chris@16
|
1044 template <unsigned Digits10, expression_template_option ExpressionTemplates>
|
Chris@16
|
1045 inline number<mpfr_float_backend<Digits10>, ExpressionTemplates> upper(const number<mpfi_float_backend<Digits10>, ExpressionTemplates>& val)
|
Chris@16
|
1046 {
|
Chris@16
|
1047 number<mpfr_float_backend<Digits10> > result;
|
Chris@16
|
1048 mpfr_set(result.backend().data(), val.backend().right_data(), GMP_RNDN);
|
Chris@16
|
1049 return result;
|
Chris@16
|
1050 }
|
Chris@16
|
1051
|
Chris@16
|
1052 template <unsigned Digits10, expression_template_option ExpressionTemplates>
|
Chris@16
|
1053 inline number<mpfr_float_backend<Digits10>, ExpressionTemplates> median(const number<mpfi_float_backend<Digits10>, ExpressionTemplates>& val)
|
Chris@16
|
1054 {
|
Chris@16
|
1055 number<mpfr_float_backend<Digits10> > result;
|
Chris@16
|
1056 mpfi_mid(result.backend().data(), val.backend().data());
|
Chris@16
|
1057 return result;
|
Chris@16
|
1058 }
|
Chris@16
|
1059
|
Chris@16
|
1060 template <unsigned Digits10, expression_template_option ExpressionTemplates>
|
Chris@16
|
1061 inline number<mpfr_float_backend<Digits10>, ExpressionTemplates> width(const number<mpfi_float_backend<Digits10>, ExpressionTemplates>& val)
|
Chris@16
|
1062 {
|
Chris@16
|
1063 number<mpfr_float_backend<Digits10> > result;
|
Chris@16
|
1064 mpfi_diam_abs(result.backend().data(), val.backend().data());
|
Chris@16
|
1065 return result;
|
Chris@16
|
1066 }
|
Chris@16
|
1067
|
Chris@16
|
1068 template <unsigned Digits10, expression_template_option ExpressionTemplates>
|
Chris@16
|
1069 inline number<mpfi_float_backend<Digits10>, ExpressionTemplates> intersect(const number<mpfi_float_backend<Digits10>, ExpressionTemplates>& a, const number<mpfi_float_backend<Digits10>, ExpressionTemplates>& b)
|
Chris@16
|
1070 {
|
Chris@16
|
1071 number<mpfi_float_backend<Digits10>, ExpressionTemplates> result;
|
Chris@16
|
1072 mpfi_intersect(result.backend().data(), a.backend().data(), b.backend().data());
|
Chris@16
|
1073 return result;
|
Chris@16
|
1074 }
|
Chris@16
|
1075
|
Chris@16
|
1076 template <unsigned Digits10, expression_template_option ExpressionTemplates>
|
Chris@16
|
1077 inline number<mpfi_float_backend<Digits10>, ExpressionTemplates> hull(const number<mpfi_float_backend<Digits10>, ExpressionTemplates>& a, const number<mpfi_float_backend<Digits10>, ExpressionTemplates>& b)
|
Chris@16
|
1078 {
|
Chris@16
|
1079 number<mpfi_float_backend<Digits10>, ExpressionTemplates> result;
|
Chris@16
|
1080 mpfi_union(result.backend().data(), a.backend().data(), b.backend().data());
|
Chris@16
|
1081 return result;
|
Chris@16
|
1082 }
|
Chris@16
|
1083
|
Chris@16
|
1084 template <unsigned Digits10, expression_template_option ExpressionTemplates>
|
Chris@16
|
1085 inline bool overlap(const number<mpfi_float_backend<Digits10>, ExpressionTemplates>& a, const number<mpfi_float_backend<Digits10>, ExpressionTemplates>& b)
|
Chris@16
|
1086 {
|
Chris@16
|
1087 return (lower(a) <= lower(b) && lower(b) <= upper(a)) ||
|
Chris@16
|
1088 (lower(b) <= lower(a) && lower(a) <= upper(b));
|
Chris@16
|
1089 }
|
Chris@16
|
1090
|
Chris@16
|
1091 template <unsigned Digits10, expression_template_option ExpressionTemplates1, expression_template_option ExpressionTemplates2>
|
Chris@16
|
1092 inline bool in(const number<mpfr_float_backend<Digits10>, ExpressionTemplates1>& a, const number<mpfi_float_backend<Digits10>, ExpressionTemplates2>& b)
|
Chris@16
|
1093 {
|
Chris@16
|
1094 return mpfi_is_inside_fr(a.backend().data(), b.backend().data()) != 0;
|
Chris@16
|
1095 }
|
Chris@16
|
1096
|
Chris@16
|
1097 template <unsigned Digits10, expression_template_option ExpressionTemplates>
|
Chris@16
|
1098 inline bool zero_in(const number<mpfi_float_backend<Digits10>, ExpressionTemplates>& a)
|
Chris@16
|
1099 {
|
Chris@16
|
1100 return mpfi_has_zero(a.backend().data()) != 0;
|
Chris@16
|
1101 }
|
Chris@16
|
1102
|
Chris@16
|
1103 template <unsigned Digits10, expression_template_option ExpressionTemplates>
|
Chris@16
|
1104 inline bool subset(const number<mpfi_float_backend<Digits10>, ExpressionTemplates>& a, const number<mpfi_float_backend<Digits10>, ExpressionTemplates>& b)
|
Chris@16
|
1105 {
|
Chris@16
|
1106 return mpfi_is_inside(a.backend().data(), b.backend().data()) != 0;
|
Chris@16
|
1107 }
|
Chris@16
|
1108
|
Chris@16
|
1109 template <unsigned Digits10, expression_template_option ExpressionTemplates>
|
Chris@16
|
1110 inline bool proper_subset(const number<mpfi_float_backend<Digits10>, ExpressionTemplates>& a, const number<mpfi_float_backend<Digits10>, ExpressionTemplates>& b)
|
Chris@16
|
1111 {
|
Chris@16
|
1112 return mpfi_is_strictly_inside(a.backend().data(), b.backend().data()) != 0;
|
Chris@16
|
1113 }
|
Chris@16
|
1114
|
Chris@16
|
1115 template <unsigned Digits10, expression_template_option ExpressionTemplates>
|
Chris@16
|
1116 inline bool empty(const number<mpfi_float_backend<Digits10>, ExpressionTemplates>& a)
|
Chris@16
|
1117 {
|
Chris@16
|
1118 return mpfi_is_empty(a.backend().data()) != 0;
|
Chris@16
|
1119 }
|
Chris@16
|
1120
|
Chris@16
|
1121 template <unsigned Digits10, expression_template_option ExpressionTemplates>
|
Chris@16
|
1122 inline bool singleton(const number<mpfi_float_backend<Digits10>, ExpressionTemplates>& a)
|
Chris@16
|
1123 {
|
Chris@16
|
1124 return mpfr_cmp(a.backend().left_data(), a.backend().right_data()) == 0;
|
Chris@16
|
1125 }
|
Chris@16
|
1126
|
Chris@16
|
1127 template <unsigned Digits10, expression_template_option ExpressionTemplates>
|
Chris@16
|
1128 struct component_type<number<mpfi_float_backend<Digits10>, ExpressionTemplates> >
|
Chris@16
|
1129 {
|
Chris@16
|
1130 typedef number<mpfr_float_backend<Digits10>, ExpressionTemplates> type;
|
Chris@16
|
1131 };
|
Chris@16
|
1132
|
Chris@16
|
1133 } // namespace multiprecision
|
Chris@16
|
1134
|
Chris@16
|
1135 namespace math{
|
Chris@16
|
1136
|
Chris@16
|
1137 namespace tools{
|
Chris@16
|
1138
|
Chris@16
|
1139 template <>
|
Chris@16
|
1140 inline int digits<boost::multiprecision::mpfi_float>()
|
Chris@16
|
1141 {
|
Chris@16
|
1142 return boost::multiprecision::backends::detail::get_default_precision();
|
Chris@16
|
1143 }
|
Chris@16
|
1144 template <>
|
Chris@16
|
1145 inline int digits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<0>, boost::multiprecision::et_off> >()
|
Chris@16
|
1146 {
|
Chris@16
|
1147 return boost::multiprecision::backends::detail::get_default_precision();
|
Chris@16
|
1148 }
|
Chris@16
|
1149
|
Chris@16
|
1150 } // namespace tools
|
Chris@16
|
1151
|
Chris@16
|
1152 namespace constants{ namespace detail{
|
Chris@16
|
1153
|
Chris@16
|
1154 template <class T> struct constant_pi;
|
Chris@16
|
1155 template <class T> struct constant_ln_two;
|
Chris@16
|
1156 template <class T> struct constant_euler;
|
Chris@16
|
1157 template <class T> struct constant_catalan;
|
Chris@16
|
1158
|
Chris@16
|
1159 //
|
Chris@16
|
1160 // Initializer: ensure all our constants are initialized prior to the first call of main:
|
Chris@16
|
1161 //
|
Chris@16
|
1162 template <class T>
|
Chris@16
|
1163 struct mpfi_initializer
|
Chris@16
|
1164 {
|
Chris@16
|
1165 struct init
|
Chris@16
|
1166 {
|
Chris@16
|
1167 init()
|
Chris@16
|
1168 {
|
Chris@16
|
1169 boost::math::constants::pi<T>();
|
Chris@16
|
1170 boost::math::constants::ln_two<T>();
|
Chris@16
|
1171 boost::math::constants::euler<T>();
|
Chris@16
|
1172 boost::math::constants::catalan<T>();
|
Chris@16
|
1173 }
|
Chris@16
|
1174 void force_instantiate()const{}
|
Chris@16
|
1175 };
|
Chris@16
|
1176 static const init initializer;
|
Chris@16
|
1177 static void force_instantiate()
|
Chris@16
|
1178 {
|
Chris@16
|
1179 initializer.force_instantiate();
|
Chris@16
|
1180 }
|
Chris@16
|
1181 };
|
Chris@16
|
1182
|
Chris@16
|
1183 template <class T>
|
Chris@16
|
1184 const typename mpfi_initializer<T>::init mpfi_initializer<T>::initializer;
|
Chris@16
|
1185
|
Chris@16
|
1186 template<unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
|
Chris@16
|
1187 struct constant_pi<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> >
|
Chris@16
|
1188 {
|
Chris@16
|
1189 typedef boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> result_type;
|
Chris@16
|
1190 template<int N>
|
Chris@16
|
1191 static inline result_type const& get(const mpl::int_<N>&)
|
Chris@16
|
1192 {
|
Chris@16
|
1193 mpfi_initializer<result_type>::force_instantiate();
|
Chris@16
|
1194 static result_type result;
|
Chris@16
|
1195 static bool has_init = false;
|
Chris@16
|
1196 if(!has_init)
|
Chris@16
|
1197 {
|
Chris@16
|
1198 has_init = true;
|
Chris@16
|
1199 mpfi_const_pi(result.backend().data());
|
Chris@16
|
1200 }
|
Chris@16
|
1201 return result;
|
Chris@16
|
1202 }
|
Chris@16
|
1203 };
|
Chris@16
|
1204 template<unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
|
Chris@16
|
1205 struct constant_ln_two<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> >
|
Chris@16
|
1206 {
|
Chris@16
|
1207 typedef boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> result_type;
|
Chris@16
|
1208 template<int N>
|
Chris@16
|
1209 static inline result_type const& get(const mpl::int_<N>&)
|
Chris@16
|
1210 {
|
Chris@16
|
1211 mpfi_initializer<result_type>::force_instantiate();
|
Chris@16
|
1212 static result_type result;
|
Chris@16
|
1213 static bool has_init = false;
|
Chris@16
|
1214 if(!has_init)
|
Chris@16
|
1215 {
|
Chris@16
|
1216 has_init = true;
|
Chris@16
|
1217 mpfi_const_log2(result.backend().data());
|
Chris@16
|
1218 }
|
Chris@16
|
1219 return result;
|
Chris@16
|
1220 }
|
Chris@16
|
1221 };
|
Chris@16
|
1222 template<unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
|
Chris@16
|
1223 struct constant_euler<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> >
|
Chris@16
|
1224 {
|
Chris@16
|
1225 typedef boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> result_type;
|
Chris@16
|
1226 template<int N>
|
Chris@16
|
1227 static inline result_type const& get(const mpl::int_<N>&)
|
Chris@16
|
1228 {
|
Chris@16
|
1229 mpfi_initializer<result_type>::force_instantiate();
|
Chris@16
|
1230 static result_type result;
|
Chris@16
|
1231 static bool has_init = false;
|
Chris@16
|
1232 if(!has_init)
|
Chris@16
|
1233 {
|
Chris@16
|
1234 has_init = true;
|
Chris@16
|
1235 mpfi_const_euler(result.backend().data());
|
Chris@16
|
1236 }
|
Chris@16
|
1237 return result;
|
Chris@16
|
1238 }
|
Chris@16
|
1239 };
|
Chris@16
|
1240 template<unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
|
Chris@16
|
1241 struct constant_catalan<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> >
|
Chris@16
|
1242 {
|
Chris@16
|
1243 typedef boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> result_type;
|
Chris@16
|
1244 template<int N>
|
Chris@16
|
1245 static inline result_type const& get(const mpl::int_<N>&)
|
Chris@16
|
1246 {
|
Chris@16
|
1247 mpfi_initializer<result_type>::force_instantiate();
|
Chris@16
|
1248 static result_type result;
|
Chris@16
|
1249 static bool has_init = false;
|
Chris@16
|
1250 if(!has_init)
|
Chris@16
|
1251 {
|
Chris@16
|
1252 has_init = true;
|
Chris@16
|
1253 mpfi_const_catalan(result.backend().data());
|
Chris@16
|
1254 }
|
Chris@16
|
1255 return result;
|
Chris@16
|
1256 }
|
Chris@16
|
1257 };
|
Chris@16
|
1258
|
Chris@16
|
1259 }} // namespaces
|
Chris@16
|
1260
|
Chris@16
|
1261 }} // namespaces
|
Chris@16
|
1262
|
Chris@16
|
1263 namespace std{
|
Chris@16
|
1264
|
Chris@16
|
1265 //
|
Chris@16
|
1266 // numeric_limits [partial] specializations for the types declared in this header:
|
Chris@16
|
1267 //
|
Chris@16
|
1268 template<unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
|
Chris@16
|
1269 class numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> >
|
Chris@16
|
1270 {
|
Chris@16
|
1271 typedef boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> number_type;
|
Chris@16
|
1272 public:
|
Chris@16
|
1273 BOOST_STATIC_CONSTEXPR bool is_specialized = true;
|
Chris@16
|
1274 static number_type (min)()
|
Chris@16
|
1275 {
|
Chris@16
|
1276 initializer.do_nothing();
|
Chris@16
|
1277 static std::pair<bool, number_type> value;
|
Chris@16
|
1278 if(!value.first)
|
Chris@16
|
1279 {
|
Chris@16
|
1280 value.first = true;
|
Chris@16
|
1281 value.second = 0.5;
|
Chris@16
|
1282 mpfi_div_2exp(value.second.backend().data(), value.second.backend().data(), -mpfr_get_emin());
|
Chris@16
|
1283 }
|
Chris@16
|
1284 return value.second;
|
Chris@16
|
1285 }
|
Chris@16
|
1286 static number_type (max)()
|
Chris@16
|
1287 {
|
Chris@16
|
1288 initializer.do_nothing();
|
Chris@16
|
1289 static std::pair<bool, number_type> value;
|
Chris@16
|
1290 if(!value.first)
|
Chris@16
|
1291 {
|
Chris@16
|
1292 value.first = true;
|
Chris@16
|
1293 value.second = 0.5;
|
Chris@16
|
1294 mpfi_mul_2exp(value.second.backend().data(), value.second.backend().data(), mpfr_get_emax());
|
Chris@16
|
1295 }
|
Chris@16
|
1296 return value.second;
|
Chris@16
|
1297 }
|
Chris@16
|
1298 BOOST_STATIC_CONSTEXPR number_type lowest()
|
Chris@16
|
1299 {
|
Chris@16
|
1300 return -(max)();
|
Chris@16
|
1301 }
|
Chris@16
|
1302 BOOST_STATIC_CONSTEXPR int digits = static_cast<int>((Digits10 * 1000L) / 301L + ((Digits10 * 1000L) % 301 ? 2 : 1));
|
Chris@16
|
1303 BOOST_STATIC_CONSTEXPR int digits10 = Digits10;
|
Chris@16
|
1304 // Is this really correct???
|
Chris@16
|
1305 BOOST_STATIC_CONSTEXPR int max_digits10 = Digits10 + 2;
|
Chris@16
|
1306 BOOST_STATIC_CONSTEXPR bool is_signed = true;
|
Chris@16
|
1307 BOOST_STATIC_CONSTEXPR bool is_integer = false;
|
Chris@16
|
1308 BOOST_STATIC_CONSTEXPR bool is_exact = false;
|
Chris@16
|
1309 BOOST_STATIC_CONSTEXPR int radix = 2;
|
Chris@16
|
1310 static number_type epsilon()
|
Chris@16
|
1311 {
|
Chris@16
|
1312 initializer.do_nothing();
|
Chris@16
|
1313 static std::pair<bool, number_type> value;
|
Chris@16
|
1314 if(!value.first)
|
Chris@16
|
1315 {
|
Chris@16
|
1316 value.first = true;
|
Chris@16
|
1317 value.second = 1;
|
Chris@16
|
1318 mpfi_div_2exp(value.second.backend().data(), value.second.backend().data(), std::numeric_limits<number_type>::digits - 1);
|
Chris@16
|
1319 }
|
Chris@16
|
1320 return value.second;
|
Chris@16
|
1321 }
|
Chris@16
|
1322 // What value should this be????
|
Chris@16
|
1323 static number_type round_error()
|
Chris@16
|
1324 {
|
Chris@16
|
1325 // returns epsilon/2
|
Chris@16
|
1326 initializer.do_nothing();
|
Chris@16
|
1327 static std::pair<bool, number_type> value;
|
Chris@16
|
1328 if(!value.first)
|
Chris@16
|
1329 {
|
Chris@16
|
1330 value.first = true;
|
Chris@16
|
1331 value.second = 1;
|
Chris@16
|
1332 mpfi_div_2exp(value.second.backend().data(), value.second.backend().data(), 1);
|
Chris@16
|
1333 }
|
Chris@16
|
1334 return value.second;
|
Chris@16
|
1335 }
|
Chris@16
|
1336 BOOST_STATIC_CONSTEXPR long min_exponent = MPFR_EMIN_DEFAULT;
|
Chris@16
|
1337 BOOST_STATIC_CONSTEXPR long min_exponent10 = (MPFR_EMIN_DEFAULT / 1000) * 301L;
|
Chris@16
|
1338 BOOST_STATIC_CONSTEXPR long max_exponent = MPFR_EMAX_DEFAULT;
|
Chris@16
|
1339 BOOST_STATIC_CONSTEXPR long max_exponent10 = (MPFR_EMAX_DEFAULT / 1000) * 301L;
|
Chris@16
|
1340 BOOST_STATIC_CONSTEXPR bool has_infinity = true;
|
Chris@16
|
1341 BOOST_STATIC_CONSTEXPR bool has_quiet_NaN = true;
|
Chris@16
|
1342 BOOST_STATIC_CONSTEXPR bool has_signaling_NaN = false;
|
Chris@16
|
1343 BOOST_STATIC_CONSTEXPR float_denorm_style has_denorm = denorm_absent;
|
Chris@16
|
1344 BOOST_STATIC_CONSTEXPR bool has_denorm_loss = false;
|
Chris@16
|
1345 static number_type infinity()
|
Chris@16
|
1346 {
|
Chris@16
|
1347 initializer.do_nothing();
|
Chris@16
|
1348 static std::pair<bool, number_type> value;
|
Chris@16
|
1349 if(!value.first)
|
Chris@16
|
1350 {
|
Chris@16
|
1351 boost::multiprecision::mpfr_float_backend<Digits10> t;
|
Chris@16
|
1352 mpfr_set_inf(t.data(), 1);
|
Chris@16
|
1353 value.first = true;
|
Chris@16
|
1354 mpfi_set_fr(value.second.backend().data(), t.data());
|
Chris@16
|
1355 }
|
Chris@16
|
1356 return value.second;
|
Chris@16
|
1357 }
|
Chris@16
|
1358 static number_type quiet_NaN()
|
Chris@16
|
1359 {
|
Chris@16
|
1360 initializer.do_nothing();
|
Chris@16
|
1361 static std::pair<bool, number_type> value;
|
Chris@16
|
1362 if(!value.first)
|
Chris@16
|
1363 {
|
Chris@16
|
1364 boost::multiprecision::mpfr_float_backend<Digits10> t;
|
Chris@16
|
1365 mpfr_set_nan(t.data());
|
Chris@16
|
1366 value.first = true;
|
Chris@16
|
1367 mpfi_set_fr(value.second.backend().data(), t.data());
|
Chris@16
|
1368 }
|
Chris@16
|
1369 return value.second;
|
Chris@16
|
1370 }
|
Chris@16
|
1371 BOOST_STATIC_CONSTEXPR number_type signaling_NaN()
|
Chris@16
|
1372 {
|
Chris@16
|
1373 return number_type(0);
|
Chris@16
|
1374 }
|
Chris@16
|
1375 BOOST_STATIC_CONSTEXPR number_type denorm_min() { return number_type(0); }
|
Chris@16
|
1376 BOOST_STATIC_CONSTEXPR bool is_iec559 = false;
|
Chris@16
|
1377 BOOST_STATIC_CONSTEXPR bool is_bounded = true;
|
Chris@16
|
1378 BOOST_STATIC_CONSTEXPR bool is_modulo = false;
|
Chris@16
|
1379 BOOST_STATIC_CONSTEXPR bool traps = true;
|
Chris@16
|
1380 BOOST_STATIC_CONSTEXPR bool tinyness_before = false;
|
Chris@16
|
1381 BOOST_STATIC_CONSTEXPR float_round_style round_style = round_to_nearest;
|
Chris@16
|
1382
|
Chris@16
|
1383 private:
|
Chris@16
|
1384 struct data_initializer
|
Chris@16
|
1385 {
|
Chris@16
|
1386 data_initializer()
|
Chris@16
|
1387 {
|
Chris@16
|
1388 std::numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<digits10> > >::epsilon();
|
Chris@16
|
1389 std::numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<digits10> > >::round_error();
|
Chris@16
|
1390 (std::numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<digits10> > >::min)();
|
Chris@16
|
1391 (std::numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<digits10> > >::max)();
|
Chris@16
|
1392 std::numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<digits10> > >::infinity();
|
Chris@16
|
1393 std::numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<digits10> > >::quiet_NaN();
|
Chris@16
|
1394 }
|
Chris@16
|
1395 void do_nothing()const{}
|
Chris@16
|
1396 };
|
Chris@16
|
1397 static const data_initializer initializer;
|
Chris@16
|
1398 };
|
Chris@16
|
1399
|
Chris@16
|
1400 template<unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
|
Chris@16
|
1401 const typename numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> >::data_initializer numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> >::initializer;
|
Chris@16
|
1402
|
Chris@16
|
1403 #ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION
|
Chris@16
|
1404
|
Chris@16
|
1405 template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
|
Chris@16
|
1406 BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> >::digits;
|
Chris@16
|
1407 template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
|
Chris@16
|
1408 BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> >::digits10;
|
Chris@16
|
1409 template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
|
Chris@16
|
1410 BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> >::max_digits10;
|
Chris@16
|
1411 template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
|
Chris@16
|
1412 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> >::is_signed;
|
Chris@16
|
1413 template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
|
Chris@16
|
1414 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> >::is_integer;
|
Chris@16
|
1415 template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
|
Chris@16
|
1416 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> >::is_exact;
|
Chris@16
|
1417 template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
|
Chris@16
|
1418 BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> >::radix;
|
Chris@16
|
1419 template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
|
Chris@16
|
1420 BOOST_CONSTEXPR_OR_CONST long numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> >::min_exponent;
|
Chris@16
|
1421 template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
|
Chris@16
|
1422 BOOST_CONSTEXPR_OR_CONST long numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> >::min_exponent10;
|
Chris@16
|
1423 template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
|
Chris@16
|
1424 BOOST_CONSTEXPR_OR_CONST long numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> >::max_exponent;
|
Chris@16
|
1425 template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
|
Chris@16
|
1426 BOOST_CONSTEXPR_OR_CONST long numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> >::max_exponent10;
|
Chris@16
|
1427 template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
|
Chris@16
|
1428 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> >::has_infinity;
|
Chris@16
|
1429 template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
|
Chris@16
|
1430 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> >::has_quiet_NaN;
|
Chris@16
|
1431 template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
|
Chris@16
|
1432 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> >::has_signaling_NaN;
|
Chris@16
|
1433 template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
|
Chris@16
|
1434 BOOST_CONSTEXPR_OR_CONST float_denorm_style numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> >::has_denorm;
|
Chris@16
|
1435 template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
|
Chris@16
|
1436 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> >::has_denorm_loss;
|
Chris@16
|
1437 template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
|
Chris@16
|
1438 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> >::is_iec559;
|
Chris@16
|
1439 template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
|
Chris@16
|
1440 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> >::is_bounded;
|
Chris@16
|
1441 template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
|
Chris@16
|
1442 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> >::is_modulo;
|
Chris@16
|
1443 template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
|
Chris@16
|
1444 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> >::traps;
|
Chris@16
|
1445 template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
|
Chris@16
|
1446 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> >::tinyness_before;
|
Chris@16
|
1447 template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
|
Chris@16
|
1448 BOOST_CONSTEXPR_OR_CONST float_round_style numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> >::round_style;
|
Chris@16
|
1449
|
Chris@16
|
1450 #endif
|
Chris@16
|
1451
|
Chris@16
|
1452
|
Chris@16
|
1453 template<boost::multiprecision::expression_template_option ExpressionTemplates>
|
Chris@16
|
1454 class numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<0>, ExpressionTemplates> >
|
Chris@16
|
1455 {
|
Chris@16
|
1456 typedef boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<0>, ExpressionTemplates> number_type;
|
Chris@16
|
1457 public:
|
Chris@16
|
1458 BOOST_STATIC_CONSTEXPR bool is_specialized = false;
|
Chris@16
|
1459 static number_type (min)() { return number_type(0); }
|
Chris@16
|
1460 static number_type (max)() { return number_type(0); }
|
Chris@16
|
1461 static number_type lowest() { return number_type(0); }
|
Chris@16
|
1462 BOOST_STATIC_CONSTEXPR int digits = 0;
|
Chris@16
|
1463 BOOST_STATIC_CONSTEXPR int digits10 = 0;
|
Chris@16
|
1464 BOOST_STATIC_CONSTEXPR int max_digits10 = 0;
|
Chris@16
|
1465 BOOST_STATIC_CONSTEXPR bool is_signed = false;
|
Chris@16
|
1466 BOOST_STATIC_CONSTEXPR bool is_integer = false;
|
Chris@16
|
1467 BOOST_STATIC_CONSTEXPR bool is_exact = false;
|
Chris@16
|
1468 BOOST_STATIC_CONSTEXPR int radix = 0;
|
Chris@16
|
1469 static number_type epsilon() { return number_type(0); }
|
Chris@16
|
1470 static number_type round_error() { return number_type(0); }
|
Chris@16
|
1471 BOOST_STATIC_CONSTEXPR int min_exponent = 0;
|
Chris@16
|
1472 BOOST_STATIC_CONSTEXPR int min_exponent10 = 0;
|
Chris@16
|
1473 BOOST_STATIC_CONSTEXPR int max_exponent = 0;
|
Chris@16
|
1474 BOOST_STATIC_CONSTEXPR int max_exponent10 = 0;
|
Chris@16
|
1475 BOOST_STATIC_CONSTEXPR bool has_infinity = false;
|
Chris@16
|
1476 BOOST_STATIC_CONSTEXPR bool has_quiet_NaN = false;
|
Chris@16
|
1477 BOOST_STATIC_CONSTEXPR bool has_signaling_NaN = false;
|
Chris@16
|
1478 BOOST_STATIC_CONSTEXPR float_denorm_style has_denorm = denorm_absent;
|
Chris@16
|
1479 BOOST_STATIC_CONSTEXPR bool has_denorm_loss = false;
|
Chris@16
|
1480 static number_type infinity() { return number_type(0); }
|
Chris@16
|
1481 static number_type quiet_NaN() { return number_type(0); }
|
Chris@16
|
1482 static number_type signaling_NaN() { return number_type(0); }
|
Chris@16
|
1483 static number_type denorm_min() { return number_type(0); }
|
Chris@16
|
1484 BOOST_STATIC_CONSTEXPR bool is_iec559 = false;
|
Chris@16
|
1485 BOOST_STATIC_CONSTEXPR bool is_bounded = false;
|
Chris@16
|
1486 BOOST_STATIC_CONSTEXPR bool is_modulo = false;
|
Chris@16
|
1487 BOOST_STATIC_CONSTEXPR bool traps = false;
|
Chris@16
|
1488 BOOST_STATIC_CONSTEXPR bool tinyness_before = false;
|
Chris@16
|
1489 BOOST_STATIC_CONSTEXPR float_round_style round_style = round_toward_zero;
|
Chris@16
|
1490 };
|
Chris@16
|
1491
|
Chris@16
|
1492 #ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION
|
Chris@16
|
1493
|
Chris@16
|
1494 template <boost::multiprecision::expression_template_option ExpressionTemplates>
|
Chris@16
|
1495 BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<0>, ExpressionTemplates> >::digits;
|
Chris@16
|
1496 template <boost::multiprecision::expression_template_option ExpressionTemplates>
|
Chris@16
|
1497 BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<0>, ExpressionTemplates> >::digits10;
|
Chris@16
|
1498 template <boost::multiprecision::expression_template_option ExpressionTemplates>
|
Chris@16
|
1499 BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<0>, ExpressionTemplates> >::max_digits10;
|
Chris@16
|
1500 template <boost::multiprecision::expression_template_option ExpressionTemplates>
|
Chris@16
|
1501 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<0>, ExpressionTemplates> >::is_signed;
|
Chris@16
|
1502 template <boost::multiprecision::expression_template_option ExpressionTemplates>
|
Chris@16
|
1503 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<0>, ExpressionTemplates> >::is_integer;
|
Chris@16
|
1504 template <boost::multiprecision::expression_template_option ExpressionTemplates>
|
Chris@16
|
1505 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<0>, ExpressionTemplates> >::is_exact;
|
Chris@16
|
1506 template <boost::multiprecision::expression_template_option ExpressionTemplates>
|
Chris@16
|
1507 BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<0>, ExpressionTemplates> >::radix;
|
Chris@16
|
1508 template <boost::multiprecision::expression_template_option ExpressionTemplates>
|
Chris@16
|
1509 BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<0>, ExpressionTemplates> >::min_exponent;
|
Chris@16
|
1510 template <boost::multiprecision::expression_template_option ExpressionTemplates>
|
Chris@16
|
1511 BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<0>, ExpressionTemplates> >::min_exponent10;
|
Chris@16
|
1512 template <boost::multiprecision::expression_template_option ExpressionTemplates>
|
Chris@16
|
1513 BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<0>, ExpressionTemplates> >::max_exponent;
|
Chris@16
|
1514 template <boost::multiprecision::expression_template_option ExpressionTemplates>
|
Chris@16
|
1515 BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<0>, ExpressionTemplates> >::max_exponent10;
|
Chris@16
|
1516 template <boost::multiprecision::expression_template_option ExpressionTemplates>
|
Chris@16
|
1517 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<0>, ExpressionTemplates> >::has_infinity;
|
Chris@16
|
1518 template <boost::multiprecision::expression_template_option ExpressionTemplates>
|
Chris@16
|
1519 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<0>, ExpressionTemplates> >::has_quiet_NaN;
|
Chris@16
|
1520 template <boost::multiprecision::expression_template_option ExpressionTemplates>
|
Chris@16
|
1521 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<0>, ExpressionTemplates> >::has_signaling_NaN;
|
Chris@16
|
1522 template <boost::multiprecision::expression_template_option ExpressionTemplates>
|
Chris@16
|
1523 BOOST_CONSTEXPR_OR_CONST float_denorm_style numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<0>, ExpressionTemplates> >::has_denorm;
|
Chris@16
|
1524 template <boost::multiprecision::expression_template_option ExpressionTemplates>
|
Chris@16
|
1525 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<0>, ExpressionTemplates> >::has_denorm_loss;
|
Chris@16
|
1526 template <boost::multiprecision::expression_template_option ExpressionTemplates>
|
Chris@16
|
1527 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<0>, ExpressionTemplates> >::is_iec559;
|
Chris@16
|
1528 template <boost::multiprecision::expression_template_option ExpressionTemplates>
|
Chris@16
|
1529 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<0>, ExpressionTemplates> >::is_bounded;
|
Chris@16
|
1530 template <boost::multiprecision::expression_template_option ExpressionTemplates>
|
Chris@16
|
1531 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<0>, ExpressionTemplates> >::is_modulo;
|
Chris@16
|
1532 template <boost::multiprecision::expression_template_option ExpressionTemplates>
|
Chris@16
|
1533 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<0>, ExpressionTemplates> >::traps;
|
Chris@16
|
1534 template <boost::multiprecision::expression_template_option ExpressionTemplates>
|
Chris@16
|
1535 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<0>, ExpressionTemplates> >::tinyness_before;
|
Chris@16
|
1536 template <boost::multiprecision::expression_template_option ExpressionTemplates>
|
Chris@16
|
1537 BOOST_CONSTEXPR_OR_CONST float_round_style numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<0>, ExpressionTemplates> >::round_style;
|
Chris@16
|
1538
|
Chris@16
|
1539 #endif
|
Chris@16
|
1540 } // namespace std
|
Chris@16
|
1541 #endif
|