]> git.proxmox.com Git - ceph.git/blame - 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
CommitLineData
7c673cae
FG
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
26namespace boost{
27namespace multiprecision{
28namespace backends{
29
30template <unsigned digits10>
31struct mpfi_float_backend;
32
33} // namespace backends
34
35template <unsigned digits10>
36struct number_category<backends::mpfi_float_backend<digits10> > : public mpl::int_<number_kind_floating_point>{};
37
38struct interval_error : public std::runtime_error
39{
40 interval_error(const std::string& s) : std::runtime_error(s) {}
41};
42
43namespace backends{
44
45namespace detail{
46
47inline 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
58template <unsigned digits10>
59struct mpfi_float_imp;
60
61template <unsigned digits10>
62struct 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 }
322protected:
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
333template <unsigned digits10>
334struct 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
408template <>
409struct 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
482template <unsigned digits10, class T>
483inline 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}
487template <unsigned digits10, class T>
488inline 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}
492template <unsigned digits10, class T>
493inline 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
498template <unsigned D1, unsigned D2>
499inline 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}
503template <unsigned D1, unsigned D2>
504inline 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}
508template <unsigned D1, unsigned D2>
509inline 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}
516template <unsigned D1, unsigned D2>
517inline 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}
521template <unsigned digits10>
522inline void eval_add(mpfi_float_backend<digits10>& result, unsigned long i)
523{
524 mpfi_add_ui(result.data(), result.data(), i);
525}
526template <unsigned digits10>
527inline void eval_subtract(mpfi_float_backend<digits10>& result, unsigned long i)
528{
529 mpfi_sub_ui(result.data(), result.data(), i);
530}
531template <unsigned digits10>
532inline void eval_multiply(mpfi_float_backend<digits10>& result, unsigned long i)
533{
534 mpfi_mul_ui(result.data(), result.data(), i);
535}
536template <unsigned digits10>
537inline void eval_divide(mpfi_float_backend<digits10>& result, unsigned long i)
538{
539 mpfi_div_ui(result.data(), result.data(), i);
540}
541template <unsigned digits10>
542inline 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}
549template <unsigned digits10>
550inline 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}
557template <unsigned digits10>
558inline 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}
564template <unsigned digits10>
565inline 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//
574template <unsigned D1, unsigned D2, unsigned D3>
575inline 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}
579template <unsigned D1, unsigned D2>
580inline 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}
584template <unsigned D1, unsigned D2>
585inline 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}
592template <unsigned D1, unsigned D2>
593inline 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}
597template <unsigned D1, unsigned D2>
598inline 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}
608template <unsigned D1, unsigned D2, unsigned D3>
609inline 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}
613template <unsigned D1, unsigned D2>
614inline 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}
618template <unsigned D1, unsigned D2>
619inline 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}
626template <unsigned D1, unsigned D2>
627inline 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}
631template <unsigned D1, unsigned D2>
632inline 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
643template <unsigned D1, unsigned D2, unsigned D3>
644inline 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}
651template <unsigned D1, unsigned D2>
652inline 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}
656template <unsigned D1, unsigned D2>
657inline 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}
667template <unsigned D1, unsigned D2>
668inline 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}
672template <unsigned D1, unsigned D2>
673inline 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
684template <unsigned D1, unsigned D2, unsigned D3>
685inline 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}
689template <unsigned D1, unsigned D2>
690inline 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}
694template <unsigned D1, unsigned D2>
695inline 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}
705template <unsigned D1, unsigned D2>
706inline 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}
710template <unsigned D1, unsigned D2>
711inline 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
722template <unsigned digits10>
723inline bool eval_is_zero(const mpfi_float_backend<digits10>& val) BOOST_NOEXCEPT
724{
725 return 0 != mpfi_is_zero(val.data());
726}
727template <unsigned digits10>
728inline int eval_get_sign(const mpfi_float_backend<digits10>& val)
729{
730 return detail::mpfi_sgn(val.data());
731}
732
733template <unsigned digits10>
734inline 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}
740template <unsigned digits10>
741inline 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
748template <unsigned digits10>
749inline 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}
755template <unsigned digits10>
756inline 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
763template <unsigned digits10>
764inline void eval_convert_to(double* result, const mpfi_float_backend<digits10>& val) BOOST_NOEXCEPT
765{
766 *result = mpfi_get_d(val.data());
767}
768template <unsigned digits10>
769inline 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
776template <unsigned D1, unsigned D2, mpfr_allocation_type AllocationType>
777inline 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
798template <unsigned Digits10, class V>
799inline 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//
809template <unsigned Digits10>
810inline void eval_sqrt(mpfi_float_backend<Digits10>& result, const mpfi_float_backend<Digits10>& val)
811{
812 mpfi_sqrt(result.data(), val.data());
813}
814
815template <unsigned Digits10>
816inline void eval_abs(mpfi_float_backend<Digits10>& result, const mpfi_float_backend<Digits10>& val)
817{
818 mpfi_abs(result.data(), val.data());
819}
820
821template <unsigned Digits10>
822inline void eval_fabs(mpfi_float_backend<Digits10>& result, const mpfi_float_backend<Digits10>& val)
823{
824 mpfi_abs(result.data(), val.data());
825}
826template <unsigned Digits10>
827inline 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}
840template <unsigned Digits10>
841inline 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}
854template <unsigned Digits10>
855inline 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}
864template <unsigned Digits10>
865inline 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}
872template <unsigned Digits10>
873inline 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
881template <unsigned Digits10>
882inline 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
887template <unsigned Digits10>
888inline 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
948template <unsigned Digits10>
949inline void eval_exp(mpfi_float_backend<Digits10>& result, const mpfi_float_backend<Digits10>& arg)
950{
951 mpfi_exp(result.data(), arg.data());
952}
953
954template <unsigned Digits10>
955inline void eval_exp2(mpfi_float_backend<Digits10>& result, const mpfi_float_backend<Digits10>& arg)
956{
957 mpfi_exp2(result.data(), arg.data());
958}
959
960template <unsigned Digits10>
961inline void eval_log(mpfi_float_backend<Digits10>& result, const mpfi_float_backend<Digits10>& arg)
962{
963 mpfi_log(result.data(), arg.data());
964}
965
966template <unsigned Digits10>
967inline void eval_log10(mpfi_float_backend<Digits10>& result, const mpfi_float_backend<Digits10>& arg)
968{
969 mpfi_log10(result.data(), arg.data());
970}
971
972template <unsigned Digits10>
973inline void eval_sin(mpfi_float_backend<Digits10>& result, const mpfi_float_backend<Digits10>& arg)
974{
975 mpfi_sin(result.data(), arg.data());
976}
977
978template <unsigned Digits10>
979inline void eval_cos(mpfi_float_backend<Digits10>& result, const mpfi_float_backend<Digits10>& arg)
980{
981 mpfi_cos(result.data(), arg.data());
982}
983
984template <unsigned Digits10>
985inline void eval_tan(mpfi_float_backend<Digits10>& result, const mpfi_float_backend<Digits10>& arg)
986{
987 mpfi_tan(result.data(), arg.data());
988}
989
990template <unsigned Digits10>
991inline void eval_asin(mpfi_float_backend<Digits10>& result, const mpfi_float_backend<Digits10>& arg)
992{
993 mpfi_asin(result.data(), arg.data());
994}
995
996template <unsigned Digits10>
997inline void eval_acos(mpfi_float_backend<Digits10>& result, const mpfi_float_backend<Digits10>& arg)
998{
999 mpfi_acos(result.data(), arg.data());
1000}
1001
1002template <unsigned Digits10>
1003inline void eval_atan(mpfi_float_backend<Digits10>& result, const mpfi_float_backend<Digits10>& arg)
1004{
1005 mpfi_atan(result.data(), arg.data());
1006}
1007
1008template <unsigned Digits10>
1009inline 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
1014template <unsigned Digits10>
1015inline void eval_sinh(mpfi_float_backend<Digits10>& result, const mpfi_float_backend<Digits10>& arg)
1016{
1017 mpfi_sinh(result.data(), arg.data());
1018}
1019
1020template <unsigned Digits10>
1021inline void eval_cosh(mpfi_float_backend<Digits10>& result, const mpfi_float_backend<Digits10>& arg)
1022{
1023 mpfi_cosh(result.data(), arg.data());
1024}
1025
1026template <unsigned Digits10>
1027inline void eval_tanh(mpfi_float_backend<Digits10>& result, const mpfi_float_backend<Digits10>& arg)
1028{
1029 mpfi_tanh(result.data(), arg.data());
1030}
1031
1032template <unsigned Digits10>
1033inline void eval_log2(mpfi_float_backend<Digits10>& result, const mpfi_float_backend<Digits10>& arg)
1034{
1035 mpfi_log2(result.data(), arg.data());
1036}
1037
1038template <unsigned Digits10>
1039inline 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
1060template <class To, unsigned D>
1061void 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
1069template <class To, unsigned D>
1070void 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
1078template <class To, unsigned D>
1079void 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
1091namespace detail{
1092
1093template<unsigned D1, unsigned D2>
1094struct is_explicitly_convertible<backends::mpfi_float_backend<D1>, backends::mpfi_float_backend<D2> > : public mpl::true_ {};
1095
1096}
1097#endif
1098
1099template<>
1100struct number_category<detail::canonical<mpfi_t, backends::mpfi_float_backend<0> >::type> : public mpl::int_<number_kind_floating_point>{};
1101template <unsigned Digits10>
1102struct is_interval_number<backends::mpfi_float_backend<Digits10> > : public mpl::true_ {};
1103
1104using boost::multiprecision::backends::mpfi_float_backend;
1105
1106typedef number<mpfi_float_backend<50> > mpfi_float_50;
1107typedef number<mpfi_float_backend<100> > mpfi_float_100;
1108typedef number<mpfi_float_backend<500> > mpfi_float_500;
1109typedef number<mpfi_float_backend<1000> > mpfi_float_1000;
1110typedef number<mpfi_float_backend<0> > mpfi_float;
1111
1112//
1113// Special interval specific functions:
1114//
1115template <unsigned Digits10, expression_template_option ExpressionTemplates>
1116inline 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
1123template <unsigned Digits10, expression_template_option ExpressionTemplates>
1124inline 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
1131template <unsigned Digits10, expression_template_option ExpressionTemplates>
1132inline 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
1139template <unsigned Digits10, expression_template_option ExpressionTemplates>
1140inline 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
1147template <unsigned Digits10, expression_template_option ExpressionTemplates>
1148inline 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
1155template <unsigned Digits10, expression_template_option ExpressionTemplates>
1156inline 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
1163template <unsigned Digits10, expression_template_option ExpressionTemplates>
1164inline 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
1170template <unsigned Digits10, expression_template_option ExpressionTemplates1, expression_template_option ExpressionTemplates2>
1171inline 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
1176template <unsigned Digits10, expression_template_option ExpressionTemplates>
1177inline bool zero_in(const number<mpfi_float_backend<Digits10>, ExpressionTemplates>& a)
1178{
1179 return mpfi_has_zero(a.backend().data()) != 0;
1180}
1181
1182template <unsigned Digits10, expression_template_option ExpressionTemplates>
1183inline 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
1188template <unsigned Digits10, expression_template_option ExpressionTemplates>
1189inline 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
1194template <unsigned Digits10, expression_template_option ExpressionTemplates>
1195inline bool empty(const number<mpfi_float_backend<Digits10>, ExpressionTemplates>& a)
1196{
1197 return mpfi_is_empty(a.backend().data()) != 0;
1198}
1199
1200template <unsigned Digits10, expression_template_option ExpressionTemplates>
1201inline 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
1206template <unsigned Digits10, expression_template_option ExpressionTemplates>
1207struct 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//
1215template <unsigned Digits10, expression_template_option ExpressionTemplates>
1216inline 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}
1222template <unsigned Digits10, expression_template_option ExpressionTemplates>
1223inline 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}
1229template <unsigned Digits10, expression_template_option ExpressionTemplates>
1230inline 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}
1236template <unsigned Digits10, expression_template_option ExpressionTemplates>
1237inline 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}
1243template <unsigned Digits10, expression_template_option ExpressionTemplates>
1244inline 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}
1250template <unsigned Digits10, expression_template_option ExpressionTemplates>
1251inline 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
1261namespace math{
1262
1263namespace tools{
1264
1265template <>
1266inline 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}
1273template <>
1274inline 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
1282template <>
1283inline boost::multiprecision::mpfi_float
1284max_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
1292template <>
1293inline boost::multiprecision::mpfi_float
1294min_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
1302template <>
1303inline boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<0>, boost::multiprecision::et_off>
1304max_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
1312template <>
1313inline boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<0>, boost::multiprecision::et_off>
1314min_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:
1323typedef boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfi_float::backend_type>, boost::multiprecision::et_on> logged_type1;
1324typedef boost::multiprecision::number<boost::multiprecision::backends::logged_adaptor<boost::multiprecision::mpfi_float::backend_type>, boost::multiprecision::et_off> logged_type2;
1325
1326template <>
1327inline int digits<logged_type1>()
1328#ifdef BOOST_MATH_NOEXCEPT
1329BOOST_NOEXCEPT
1330#endif
1331{
1332 return multiprecision::detail::digits10_2_2(logged_type1::default_precision());
1333}
1334template <>
1335inline int digits<logged_type2 >()
1336#ifdef BOOST_MATH_NOEXCEPT
1337BOOST_NOEXCEPT
1338#endif
1339{
1340 return multiprecision::detail::digits10_2_2(logged_type1::default_precision());
1341}
1342
1343template <>
1344inline logged_type1
1345max_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
1353template <>
1354inline logged_type1
1355min_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
1363template <>
1364inline logged_type2
1365max_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
1373template <>
1374inline logged_type2
1375min_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
1384namespace constants{ namespace detail{
1385
1386template <class T> struct constant_pi;
1387template <class T> struct constant_ln_two;
1388template <class T> struct constant_euler;
1389template <class T> struct constant_catalan;
1390
1391//
1392// Initializer: ensure all our constants are initialized prior to the first call of main:
1393//
1394template <class T>
1395struct 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
1415template <class T>
1416const typename mpfi_initializer<T>::init mpfi_initializer<T>::initializer;
1417
1418template<unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
1419struct 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};
1442template<unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
1443struct 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};
1466template<unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
1467struct 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};
1490template<unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
1491struct 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
1519namespace std{
1520
1521//
1522// numeric_limits [partial] specializations for the types declared in this header:
1523//
1524template<unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
1525class 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;
1528public:
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
1639private:
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
1656template<unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
1657const 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
1661template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
1662BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> >::digits;
1663template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
1664BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> >::digits10;
1665template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
1666BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> >::max_digits10;
1667template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
1668BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> >::is_signed;
1669template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
1670BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> >::is_integer;
1671template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
1672BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> >::is_exact;
1673template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
1674BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> >::radix;
1675template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
1676BOOST_CONSTEXPR_OR_CONST long numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> >::min_exponent;
1677template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
1678BOOST_CONSTEXPR_OR_CONST long numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> >::min_exponent10;
1679template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
1680BOOST_CONSTEXPR_OR_CONST long numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> >::max_exponent;
1681template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
1682BOOST_CONSTEXPR_OR_CONST long numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> >::max_exponent10;
1683template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
1684BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> >::has_infinity;
1685template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
1686BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> >::has_quiet_NaN;
1687template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
1688BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> >::has_signaling_NaN;
1689template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
1690BOOST_CONSTEXPR_OR_CONST float_denorm_style numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> >::has_denorm;
1691template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
1692BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> >::has_denorm_loss;
1693template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
1694BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> >::is_iec559;
1695template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
1696BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> >::is_bounded;
1697template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
1698BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> >::is_modulo;
1699template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
1700BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> >::traps;
1701template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
1702BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> >::tinyness_before;
1703template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
1704BOOST_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
1709template<boost::multiprecision::expression_template_option ExpressionTemplates>
1710class 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;
1713public:
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
1750template <boost::multiprecision::expression_template_option ExpressionTemplates>
1751BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<0>, ExpressionTemplates> >::digits;
1752template <boost::multiprecision::expression_template_option ExpressionTemplates>
1753BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<0>, ExpressionTemplates> >::digits10;
1754template <boost::multiprecision::expression_template_option ExpressionTemplates>
1755BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<0>, ExpressionTemplates> >::max_digits10;
1756template <boost::multiprecision::expression_template_option ExpressionTemplates>
1757BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<0>, ExpressionTemplates> >::is_signed;
1758template <boost::multiprecision::expression_template_option ExpressionTemplates>
1759BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<0>, ExpressionTemplates> >::is_integer;
1760template <boost::multiprecision::expression_template_option ExpressionTemplates>
1761BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<0>, ExpressionTemplates> >::is_exact;
1762template <boost::multiprecision::expression_template_option ExpressionTemplates>
1763BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<0>, ExpressionTemplates> >::radix;
1764template <boost::multiprecision::expression_template_option ExpressionTemplates>
1765BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<0>, ExpressionTemplates> >::min_exponent;
1766template <boost::multiprecision::expression_template_option ExpressionTemplates>
1767BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<0>, ExpressionTemplates> >::min_exponent10;
1768template <boost::multiprecision::expression_template_option ExpressionTemplates>
1769BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<0>, ExpressionTemplates> >::max_exponent;
1770template <boost::multiprecision::expression_template_option ExpressionTemplates>
1771BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<0>, ExpressionTemplates> >::max_exponent10;
1772template <boost::multiprecision::expression_template_option ExpressionTemplates>
1773BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<0>, ExpressionTemplates> >::has_infinity;
1774template <boost::multiprecision::expression_template_option ExpressionTemplates>
1775BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<0>, ExpressionTemplates> >::has_quiet_NaN;
1776template <boost::multiprecision::expression_template_option ExpressionTemplates>
1777BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<0>, ExpressionTemplates> >::has_signaling_NaN;
1778template <boost::multiprecision::expression_template_option ExpressionTemplates>
1779BOOST_CONSTEXPR_OR_CONST float_denorm_style numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<0>, ExpressionTemplates> >::has_denorm;
1780template <boost::multiprecision::expression_template_option ExpressionTemplates>
1781BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<0>, ExpressionTemplates> >::has_denorm_loss;
1782template <boost::multiprecision::expression_template_option ExpressionTemplates>
1783BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<0>, ExpressionTemplates> >::is_iec559;
1784template <boost::multiprecision::expression_template_option ExpressionTemplates>
1785BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<0>, ExpressionTemplates> >::is_bounded;
1786template <boost::multiprecision::expression_template_option ExpressionTemplates>
1787BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<0>, ExpressionTemplates> >::is_modulo;
1788template <boost::multiprecision::expression_template_option ExpressionTemplates>
1789BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<0>, ExpressionTemplates> >::traps;
1790template <boost::multiprecision::expression_template_option ExpressionTemplates>
1791BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<0>, ExpressionTemplates> >::tinyness_before;
1792template <boost::multiprecision::expression_template_option ExpressionTemplates>
1793BOOST_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