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