]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/libs/multiprecision/include/boost/multiprecision/mpfr.hpp
bump version to 12.2.2-pve1
[ceph.git] / ceph / src / boost / libs / multiprecision / include / boost / multiprecision / mpfr.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_MPFR_HPP
7#define BOOST_MATH_BN_MPFR_HPP
8
9#include <boost/multiprecision/number.hpp>
10#include <boost/multiprecision/debug_adaptor.hpp>
11#include <boost/multiprecision/gmp.hpp>
12#include <boost/math/special_functions/fpclassify.hpp>
13#include <boost/cstdint.hpp>
14#include <boost/multiprecision/detail/big_lanczos.hpp>
15#include <boost/multiprecision/detail/digits.hpp>
16#include <mpfr.h>
17#include <cmath>
18#include <algorithm>
19
20#ifndef BOOST_MULTIPRECISION_MPFR_DEFAULT_PRECISION
21# define BOOST_MULTIPRECISION_MPFR_DEFAULT_PRECISION 20
22#endif
23
24namespace boost{
25namespace multiprecision{
26
27enum mpfr_allocation_type
28{
29 allocate_stack,
30 allocate_dynamic
31};
32
33namespace backends{
34
35template <unsigned digits10, mpfr_allocation_type AllocationType = allocate_dynamic>
36struct mpfr_float_backend;
37
38template <>
39struct mpfr_float_backend<0, allocate_stack>;
40
41} // namespace backends
42
43template <unsigned digits10, mpfr_allocation_type AllocationType>
44struct number_category<backends::mpfr_float_backend<digits10, AllocationType> > : public mpl::int_<number_kind_floating_point>{};
45
46namespace backends{
47
48namespace detail{
49
50template <bool b>
51struct mpfr_cleanup
52{
53 struct initializer
54 {
55 initializer() {}
56 ~initializer(){ mpfr_free_cache(); }
57 void force_instantiate()const {}
58 };
59 static const initializer init;
60 static void force_instantiate() { init.force_instantiate(); }
61};
62
63template <bool b>
64typename mpfr_cleanup<b>::initializer const mpfr_cleanup<b>::init;
65
66
67template <unsigned digits10, mpfr_allocation_type AllocationType>
68struct mpfr_float_imp;
69
70template <unsigned digits10>
71struct mpfr_float_imp<digits10, allocate_dynamic>
72{
73#ifdef BOOST_HAS_LONG_LONG
74 typedef mpl::list<long, boost::long_long_type> signed_types;
75 typedef mpl::list<unsigned long, boost::ulong_long_type> unsigned_types;
76#else
77 typedef mpl::list<long> signed_types;
78 typedef mpl::list<unsigned long> unsigned_types;
79#endif
80 typedef mpl::list<double, long double> float_types;
81 typedef long exponent_type;
82
83 mpfr_float_imp()
84 {
85 mpfr_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision()));
86 mpfr_set_ui(m_data, 0u, GMP_RNDN);
87 }
88 mpfr_float_imp(unsigned prec)
89 {
90 mpfr_init2(m_data, prec);
91 mpfr_set_ui(m_data, 0u, GMP_RNDN);
92 }
93
94 mpfr_float_imp(const mpfr_float_imp& o)
95 {
96 mpfr_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision()));
97 if(o.m_data[0]._mpfr_d)
98 mpfr_set(m_data, o.m_data, GMP_RNDN);
99 }
100#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
101 mpfr_float_imp(mpfr_float_imp&& o) BOOST_NOEXCEPT
102 {
103 m_data[0] = o.m_data[0];
104 o.m_data[0]._mpfr_d = 0;
105 }
106#endif
107 mpfr_float_imp& operator = (const mpfr_float_imp& o)
108 {
109 if(m_data[0]._mpfr_d == 0)
110 mpfr_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision()));
111 if(o.m_data[0]._mpfr_d)
112 mpfr_set(m_data, o.m_data, GMP_RNDN);
113 return *this;
114 }
115#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
116 mpfr_float_imp& operator = (mpfr_float_imp&& o) BOOST_NOEXCEPT
117 {
118 mpfr_swap(m_data, o.m_data);
119 return *this;
120 }
121#endif
122#ifdef BOOST_HAS_LONG_LONG
123#ifdef _MPFR_H_HAVE_INTMAX_T
124 mpfr_float_imp& operator = (boost::ulong_long_type i)
125 {
126 if(m_data[0]._mpfr_d == 0)
127 mpfr_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision()));
128 mpfr_set_uj(m_data, i, GMP_RNDN);
129 return *this;
130 }
131 mpfr_float_imp& operator = (boost::long_long_type i)
132 {
133 if(m_data[0]._mpfr_d == 0)
134 mpfr_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision()));
135 mpfr_set_sj(m_data, i, GMP_RNDN);
136 return *this;
137 }
138#else
139 mpfr_float_imp& operator = (boost::ulong_long_type i)
140 {
141 if(m_data[0]._mpfr_d == 0)
142 mpfr_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision()));
143 boost::ulong_long_type mask = ((((1uLL << (std::numeric_limits<unsigned long>::digits - 1)) - 1) << 1) | 1uLL);
144 unsigned shift = 0;
145 mpfr_t t;
146 mpfr_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))));
147 mpfr_set_ui(m_data, 0, GMP_RNDN);
148 while(i)
149 {
150 mpfr_set_ui(t, static_cast<unsigned long>(i & mask), GMP_RNDN);
151 if(shift)
152 mpfr_mul_2exp(t, t, shift, GMP_RNDN);
153 mpfr_add(m_data, m_data, t, GMP_RNDN);
154 shift += std::numeric_limits<unsigned long>::digits;
155 i >>= std::numeric_limits<unsigned long>::digits;
156 }
157 mpfr_clear(t);
158 return *this;
159 }
160 mpfr_float_imp& operator = (boost::long_long_type i)
161 {
162 if(m_data[0]._mpfr_d == 0)
163 mpfr_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision()));
164 bool neg = i < 0;
165 *this = boost::multiprecision::detail::unsigned_abs(i);
166 if(neg)
167 mpfr_neg(m_data, m_data, GMP_RNDN);
168 return *this;
169 }
170#endif
171#endif
172 mpfr_float_imp& operator = (unsigned long i)
173 {
174 if(m_data[0]._mpfr_d == 0)
175 mpfr_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision()));
176 mpfr_set_ui(m_data, i, GMP_RNDN);
177 return *this;
178 }
179 mpfr_float_imp& operator = (long i)
180 {
181 if(m_data[0]._mpfr_d == 0)
182 mpfr_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision()));
183 mpfr_set_si(m_data, i, GMP_RNDN);
184 return *this;
185 }
186 mpfr_float_imp& operator = (double d)
187 {
188 if(m_data[0]._mpfr_d == 0)
189 mpfr_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision()));
190 mpfr_set_d(m_data, d, GMP_RNDN);
191 return *this;
192 }
193 mpfr_float_imp& operator = (long double a)
194 {
195 if(m_data[0]._mpfr_d == 0)
196 mpfr_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision()));
197 mpfr_set_ld(m_data, a, GMP_RNDN);
198 return *this;
199 }
200 mpfr_float_imp& operator = (const char* s)
201 {
202 if(m_data[0]._mpfr_d == 0)
203 mpfr_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision()));
204 if(mpfr_set_str(m_data, s, 10, GMP_RNDN) != 0)
205 {
206 BOOST_THROW_EXCEPTION(std::runtime_error(std::string("Unable to parse string \"") + s + std::string("\"as a valid floating point number.")));
207 }
208 return *this;
209 }
210 void swap(mpfr_float_imp& o) BOOST_NOEXCEPT
211 {
212 mpfr_swap(m_data, o.m_data);
213 }
214 std::string str(std::streamsize digits, std::ios_base::fmtflags f)const
215 {
216 BOOST_ASSERT(m_data[0]._mpfr_d);
217
218 bool scientific = (f & std::ios_base::scientific) == std::ios_base::scientific;
219 bool fixed = (f & std::ios_base::fixed) == std::ios_base::fixed;
220
221 std::streamsize org_digits(digits);
222
223 if(scientific && digits)
224 ++digits;
225
226 std::string result;
227 mp_exp_t e;
228 if(mpfr_inf_p(m_data))
229 {
230 if(mpfr_sgn(m_data) < 0)
231 result = "-inf";
232 else if(f & std::ios_base::showpos)
233 result = "+inf";
234 else
235 result = "inf";
236 return result;
237 }
238 if(mpfr_nan_p(m_data))
239 {
240 result = "nan";
241 return result;
242 }
243 if(mpfr_zero_p(m_data))
244 {
245 e = 0;
246 result = "0";
247 }
248 else
249 {
250 char* ps = mpfr_get_str (0, &e, 10, static_cast<std::size_t>(digits), m_data, GMP_RNDN);
251 --e; // To match with what our formatter expects.
252 if(fixed && e != -1)
253 {
254 // Oops we actually need a different number of digits to what we asked for:
255 mpfr_free_str(ps);
256 digits += e + 1;
257 if(digits == 0)
258 {
259 // We need to get *all* the digits and then possibly round up,
260 // we end up with either "0" or "1" as the result.
261 ps = mpfr_get_str (0, &e, 10, 0, m_data, GMP_RNDN);
262 --e;
263 unsigned offset = *ps == '-' ? 1 : 0;
264 if(ps[offset] > '5')
265 {
266 ++e;
267 ps[offset] = '1';
268 ps[offset + 1] = 0;
269 }
270 else if(ps[offset] == '5')
271 {
272 unsigned i = offset + 1;
273 bool round_up = false;
274 while(ps[i] != 0)
275 {
276 if(ps[i] != '0')
277 {
278 round_up = true;
279 break;
280 }
281 }
282 if(round_up)
283 {
284 ++e;
285 ps[offset] = '1';
286 ps[offset + 1] = 0;
287 }
288 else
289 {
290 ps[offset] = '0';
291 ps[offset + 1] = 0;
292 }
293 }
294 else
295 {
296 ps[offset] = '0';
297 ps[offset + 1] = 0;
298 }
299 }
300 else if(digits > 0)
301 {
302 ps = mpfr_get_str (0, &e, 10, static_cast<std::size_t>(digits), m_data, GMP_RNDN);
303 --e; // To match with what our formatter expects.
304 }
305 else
306 {
307 ps = mpfr_get_str (0, &e, 10, 1, m_data, GMP_RNDN);
308 --e;
309 unsigned offset = *ps == '-' ? 1 : 0;
310 ps[offset] = '0';
311 ps[offset + 1] = 0;
312 }
313 }
314 result = ps ? ps : "0";
315 if(ps)
316 mpfr_free_str(ps);
317 }
318 boost::multiprecision::detail::format_float_string(result, e, org_digits, f, 0 != mpfr_zero_p(m_data));
319 return result;
320 }
321 ~mpfr_float_imp() BOOST_NOEXCEPT
322 {
323 if(m_data[0]._mpfr_d)
324 mpfr_clear(m_data);
325 detail::mpfr_cleanup<true>::force_instantiate();
326 }
327 void negate() BOOST_NOEXCEPT
328 {
329 BOOST_ASSERT(m_data[0]._mpfr_d);
330 mpfr_neg(m_data, m_data, GMP_RNDN);
331 }
332 template <mpfr_allocation_type AllocationType>
333 int compare(const mpfr_float_backend<digits10, AllocationType>& o)const BOOST_NOEXCEPT
334 {
335 BOOST_ASSERT(m_data[0]._mpfr_d && o.m_data[0]._mpfr_d);
336 return mpfr_cmp(m_data, o.m_data);
337 }
338 int compare(long i)const BOOST_NOEXCEPT
339 {
340 BOOST_ASSERT(m_data[0]._mpfr_d);
341 return mpfr_cmp_si(m_data, i);
342 }
343 int compare(unsigned long i)const BOOST_NOEXCEPT
344 {
345 BOOST_ASSERT(m_data[0]._mpfr_d);
346 return mpfr_cmp_ui(m_data, i);
347 }
348 template <class V>
349 int compare(V v)const BOOST_NOEXCEPT
350 {
351 mpfr_float_backend<digits10, allocate_dynamic> d;
352 d = v;
353 return compare(d);
354 }
355 mpfr_t& data() BOOST_NOEXCEPT
356 {
357 BOOST_ASSERT(m_data[0]._mpfr_d);
358 return m_data;
359 }
360 const mpfr_t& data()const BOOST_NOEXCEPT
361 {
362 BOOST_ASSERT(m_data[0]._mpfr_d);
363 return m_data;
364 }
365protected:
366 mpfr_t m_data;
367 static unsigned& get_default_precision() BOOST_NOEXCEPT
368 {
369 static unsigned val = BOOST_MULTIPRECISION_MPFR_DEFAULT_PRECISION;
370 return val;
371 }
372};
373
374#ifdef BOOST_MSVC
375#pragma warning(push)
376#pragma warning(disable:4127) // Conditional expression is constant
377#endif
378
379template <unsigned digits10>
380struct mpfr_float_imp<digits10, allocate_stack>
381{
382#ifdef BOOST_HAS_LONG_LONG
383 typedef mpl::list<long, boost::long_long_type> signed_types;
384 typedef mpl::list<unsigned long, boost::ulong_long_type> unsigned_types;
385#else
386 typedef mpl::list<long> signed_types;
387 typedef mpl::list<unsigned long> unsigned_types;
388#endif
389 typedef mpl::list<double, long double> float_types;
390 typedef long exponent_type;
391
392 static const unsigned digits2 = (digits10 * 1000uL) / 301uL + ((digits10 * 1000uL) % 301 ? 2u : 1u);
393 static const unsigned limb_count = mpfr_custom_get_size(digits2) / sizeof(mp_limb_t);
394
395 ~mpfr_float_imp() BOOST_NOEXCEPT
396 {
397 detail::mpfr_cleanup<true>::force_instantiate();
398 }
399 mpfr_float_imp()
400 {
401 mpfr_custom_init(m_buffer, digits2);
402 mpfr_custom_init_set(m_data, MPFR_NAN_KIND, 0, digits2, m_buffer);
403 mpfr_set_ui(m_data, 0u, GMP_RNDN);
404 }
405
406 mpfr_float_imp(const mpfr_float_imp& o)
407 {
408 mpfr_custom_init(m_buffer, digits2);
409 mpfr_custom_init_set(m_data, MPFR_NAN_KIND, 0, digits2, m_buffer);
410 mpfr_set(m_data, o.m_data, GMP_RNDN);
411 }
412 mpfr_float_imp& operator = (const mpfr_float_imp& o)
413 {
414 mpfr_set(m_data, o.m_data, GMP_RNDN);
415 return *this;
416 }
417#ifdef BOOST_HAS_LONG_LONG
418#ifdef _MPFR_H_HAVE_INTMAX_T
419 mpfr_float_imp& operator = (boost::ulong_long_type i)
420 {
421 mpfr_set_uj(m_data, i, GMP_RNDN);
422 return *this;
423 }
424 mpfr_float_imp& operator = (boost::long_long_type i)
425 {
426 mpfr_set_sj(m_data, i, GMP_RNDN);
427 return *this;
428 }
429#else
430 mpfr_float_imp& operator = (boost::ulong_long_type i)
431 {
432 boost::ulong_long_type mask = ((((1uLL << (std::numeric_limits<unsigned long>::digits - 1)) - 1) << 1) | 1uL);
433 unsigned shift = 0;
434 mpfr_t t;
435 mp_limb_t t_limbs[limb_count];
436 mpfr_custom_init(t_limbs, digits2);
437 mpfr_custom_init_set(t, MPFR_NAN_KIND, 0, digits2, t_limbs);
438 mpfr_set_ui(m_data, 0, GMP_RNDN);
439 while(i)
440 {
441 mpfr_set_ui(t, static_cast<unsigned long>(i & mask), GMP_RNDN);
442 if(shift)
443 mpfr_mul_2exp(t, t, shift, GMP_RNDN);
444 mpfr_add(m_data, m_data, t, GMP_RNDN);
445 shift += std::numeric_limits<unsigned long>::digits;
446 i >>= std::numeric_limits<unsigned long>::digits;
447 }
448 return *this;
449 }
450 mpfr_float_imp& operator = (boost::long_long_type i)
451 {
452 bool neg = i < 0;
453 *this = boost::multiprecision::detail::unsigned_abs(i);
454 if(neg)
455 mpfr_neg(m_data, m_data, GMP_RNDN);
456 return *this;
457 }
458#endif
459#endif
460 mpfr_float_imp& operator = (unsigned long i)
461 {
462 mpfr_set_ui(m_data, i, GMP_RNDN);
463 return *this;
464 }
465 mpfr_float_imp& operator = (long i)
466 {
467 mpfr_set_si(m_data, i, GMP_RNDN);
468 return *this;
469 }
470 mpfr_float_imp& operator = (double d)
471 {
472 mpfr_set_d(m_data, d, GMP_RNDN);
473 return *this;
474 }
475 mpfr_float_imp& operator = (long double a)
476 {
477 mpfr_set_ld(m_data, a, GMP_RNDN);
478 return *this;
479 }
480 mpfr_float_imp& operator = (const char* s)
481 {
482 if(mpfr_set_str(m_data, s, 10, GMP_RNDN) != 0)
483 {
484 BOOST_THROW_EXCEPTION(std::runtime_error(std::string("Unable to parse string \"") + s + std::string("\"as a valid floating point number.")));
485 }
486 return *this;
487 }
488 void swap(mpfr_float_imp& o) BOOST_NOEXCEPT
489 {
490 // We have to swap by copying:
491 mpfr_float_imp t(*this);
492 *this = o;
493 o = t;
494 }
495 std::string str(std::streamsize digits, std::ios_base::fmtflags f)const
496 {
497 BOOST_ASSERT(m_data[0]._mpfr_d);
498
499 bool scientific = (f & std::ios_base::scientific) == std::ios_base::scientific;
500 bool fixed = (f & std::ios_base::fixed) == std::ios_base::fixed;
501
502 std::streamsize org_digits(digits);
503
504 if(scientific && digits)
505 ++digits;
506
507 std::string result;
508 mp_exp_t e;
509 if(mpfr_inf_p(m_data))
510 {
511 if(mpfr_sgn(m_data) < 0)
512 result = "-inf";
513 else if(f & std::ios_base::showpos)
514 result = "+inf";
515 else
516 result = "inf";
517 return result;
518 }
519 if(mpfr_nan_p(m_data))
520 {
521 result = "nan";
522 return result;
523 }
524 if(mpfr_zero_p(m_data))
525 {
526 e = 0;
527 result = "0";
528 }
529 else
530 {
531 char* ps = mpfr_get_str (0, &e, 10, static_cast<std::size_t>(digits), m_data, GMP_RNDN);
532 --e; // To match with what our formatter expects.
533 if(fixed && e != -1)
534 {
535 // Oops we actually need a different number of digits to what we asked for:
536 mpfr_free_str(ps);
537 digits += e + 1;
538 if(digits == 0)
539 {
540 // We need to get *all* the digits and then possibly round up,
541 // we end up with either "0" or "1" as the result.
542 ps = mpfr_get_str (0, &e, 10, 0, m_data, GMP_RNDN);
543 --e;
544 unsigned offset = *ps == '-' ? 1 : 0;
545 if(ps[offset] > '5')
546 {
547 ++e;
548 ps[offset] = '1';
549 ps[offset + 1] = 0;
550 }
551 else if(ps[offset] == '5')
552 {
553 unsigned i = offset + 1;
554 bool round_up = false;
555 while(ps[i] != 0)
556 {
557 if(ps[i] != '0')
558 {
559 round_up = true;
560 break;
561 }
562 }
563 if(round_up)
564 {
565 ++e;
566 ps[offset] = '1';
567 ps[offset + 1] = 0;
568 }
569 else
570 {
571 ps[offset] = '0';
572 ps[offset + 1] = 0;
573 }
574 }
575 else
576 {
577 ps[offset] = '0';
578 ps[offset + 1] = 0;
579 }
580 }
581 else if(digits > 0)
582 {
583 ps = mpfr_get_str (0, &e, 10, static_cast<std::size_t>(digits), m_data, GMP_RNDN);
584 --e; // To match with what our formatter expects.
585 }
586 else
587 {
588 ps = mpfr_get_str (0, &e, 10, 1, m_data, GMP_RNDN);
589 --e;
590 unsigned offset = *ps == '-' ? 1 : 0;
591 ps[offset] = '0';
592 ps[offset + 1] = 0;
593 }
594 }
595 result = ps ? ps : "0";
596 if(ps)
597 mpfr_free_str(ps);
598 }
599 boost::multiprecision::detail::format_float_string(result, e, org_digits, f, 0 != mpfr_zero_p(m_data));
600 return result;
601 }
602 void negate() BOOST_NOEXCEPT
603 {
604 mpfr_neg(m_data, m_data, GMP_RNDN);
605 }
606 template <mpfr_allocation_type AllocationType>
607 int compare(const mpfr_float_backend<digits10, AllocationType>& o)const BOOST_NOEXCEPT
608 {
609 return mpfr_cmp(m_data, o.m_data);
610 }
611 int compare(long i)const BOOST_NOEXCEPT
612 {
613 return mpfr_cmp_si(m_data, i);
614 }
615 int compare(unsigned long i)const BOOST_NOEXCEPT
616 {
617 return mpfr_cmp_ui(m_data, i);
618 }
619 template <class V>
620 int compare(V v)const BOOST_NOEXCEPT
621 {
622 mpfr_float_backend<digits10, allocate_stack> d;
623 d = v;
624 return compare(d);
625 }
626 mpfr_t& data() BOOST_NOEXCEPT
627 {
628 return m_data;
629 }
630 const mpfr_t& data()const BOOST_NOEXCEPT
631 {
632 return m_data;
633 }
634protected:
635 mpfr_t m_data;
636 mp_limb_t m_buffer[limb_count];
637};
638
639#ifdef BOOST_MSVC
640#pragma warning(pop)
641#endif
642
643} // namespace detail
644
645template <unsigned digits10, mpfr_allocation_type AllocationType>
646struct mpfr_float_backend : public detail::mpfr_float_imp<digits10, AllocationType>
647{
648 mpfr_float_backend() : detail::mpfr_float_imp<digits10, AllocationType>() {}
649 mpfr_float_backend(const mpfr_float_backend& o) : detail::mpfr_float_imp<digits10, AllocationType>(o) {}
650#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
651 mpfr_float_backend(mpfr_float_backend&& o) BOOST_NOEXCEPT : detail::mpfr_float_imp<digits10, AllocationType>(static_cast<detail::mpfr_float_imp<digits10, AllocationType>&&>(o)) {}
652#endif
653 template <unsigned D, mpfr_allocation_type AT>
654 mpfr_float_backend(const mpfr_float_backend<D, AT>& val, typename enable_if_c<D <= digits10>::type* = 0)
655 : detail::mpfr_float_imp<digits10, AllocationType>()
656 {
657 mpfr_set(this->m_data, val.data(), GMP_RNDN);
658 }
659 template <unsigned D, mpfr_allocation_type AT>
660 explicit mpfr_float_backend(const mpfr_float_backend<D, AT>& val, typename disable_if_c<D <= digits10>::type* = 0)
661 : detail::mpfr_float_imp<digits10, AllocationType>()
662 {
663 mpfr_set(this->m_data, val.data(), GMP_RNDN);
664 }
665 template <unsigned D>
666 mpfr_float_backend(const gmp_float<D>& val, typename enable_if_c<D <= digits10>::type* = 0)
667 : detail::mpfr_float_imp<digits10, AllocationType>()
668 {
669 mpfr_set_f(this->m_data, val.data(), GMP_RNDN);
670 }
671 template <unsigned D>
672 mpfr_float_backend(const gmp_float<D>& val, typename disable_if_c<D <= digits10>::type* = 0)
673 : detail::mpfr_float_imp<digits10, AllocationType>()
674 {
675 mpfr_set_f(this->m_data, val.data(), GMP_RNDN);
676 }
677 mpfr_float_backend(const gmp_int& val)
678 : detail::mpfr_float_imp<digits10, AllocationType>()
679 {
680 mpfr_set_z(this->m_data, val.data(), GMP_RNDN);
681 }
682 mpfr_float_backend(const gmp_rational& val)
683 : detail::mpfr_float_imp<digits10, AllocationType>()
684 {
685 mpfr_set_q(this->m_data, val.data(), GMP_RNDN);
686 }
687 mpfr_float_backend(const mpfr_t val)
688 : detail::mpfr_float_imp<digits10, AllocationType>()
689 {
690 mpfr_set(this->m_data, val, GMP_RNDN);
691 }
692 mpfr_float_backend(const mpf_t val)
693 : detail::mpfr_float_imp<digits10, AllocationType>()
694 {
695 mpfr_set_f(this->m_data, val, GMP_RNDN);
696 }
697 mpfr_float_backend(const mpz_t val)
698 : detail::mpfr_float_imp<digits10, AllocationType>()
699 {
700 mpfr_set_z(this->m_data, val, GMP_RNDN);
701 }
702 mpfr_float_backend(const mpq_t val)
703 : detail::mpfr_float_imp<digits10, AllocationType>()
704 {
705 mpfr_set_q(this->m_data, val, GMP_RNDN);
706 }
707 mpfr_float_backend& operator=(const mpfr_float_backend& o)
708 {
709 *static_cast<detail::mpfr_float_imp<digits10, AllocationType>*>(this) = static_cast<detail::mpfr_float_imp<digits10, AllocationType> const&>(o);
710 return *this;
711 }
712#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
713 mpfr_float_backend& operator=(mpfr_float_backend&& o) BOOST_NOEXCEPT
714 {
715 *static_cast<detail::mpfr_float_imp<digits10, AllocationType>*>(this) = static_cast<detail::mpfr_float_imp<digits10, AllocationType>&&>(o);
716 return *this;
717 }
718#endif
719 template <class V>
720 mpfr_float_backend& operator=(const V& v)
721 {
722 *static_cast<detail::mpfr_float_imp<digits10, AllocationType>*>(this) = v;
723 return *this;
724 }
725 mpfr_float_backend& operator=(const mpfr_t val)
726 {
727 if(this->m_data[0]._mpfr_d == 0)
728 mpfr_init2(this->m_data, multiprecision::detail::digits10_2_2(digits10));
729 mpfr_set(this->m_data, val, GMP_RNDN);
730 return *this;
731 }
732 mpfr_float_backend& operator=(const mpf_t val)
733 {
734 if(this->m_data[0]._mpfr_d == 0)
735 mpfr_init2(this->m_data, multiprecision::detail::digits10_2_2(digits10));
736 mpfr_set_f(this->m_data, val, GMP_RNDN);
737 return *this;
738 }
739 mpfr_float_backend& operator=(const mpz_t val)
740 {
741 if(this->m_data[0]._mpfr_d == 0)
742 mpfr_init2(this->m_data, multiprecision::detail::digits10_2_2(digits10));
743 mpfr_set_z(this->m_data, val, GMP_RNDN);
744 return *this;
745 }
746 mpfr_float_backend& operator=(const mpq_t val)
747 {
748 if(this->m_data[0]._mpfr_d == 0)
749 mpfr_init2(this->m_data, multiprecision::detail::digits10_2_2(digits10));
750 mpfr_set_q(this->m_data, val, GMP_RNDN);
751 return *this;
752 }
753 // We don't change our precision here, this is a fixed precision type:
754 template <unsigned D, mpfr_allocation_type AT>
755 mpfr_float_backend& operator=(const mpfr_float_backend<D, AT>& val)
756 {
757 if(this->m_data[0]._mpfr_d == 0)
758 mpfr_init2(this->m_data, multiprecision::detail::digits10_2_2(digits10));
759 mpfr_set(this->m_data, val.data(), GMP_RNDN);
760 return *this;
761 }
762 template <unsigned D>
763 mpfr_float_backend& operator=(const gmp_float<D>& val)
764 {
765 if(this->m_data[0]._mpfr_d == 0)
766 mpfr_init2(this->m_data, multiprecision::detail::digits10_2_2(digits10));
767 mpfr_set_f(this->m_data, val.data(), GMP_RNDN);
768 return *this;
769 }
770 mpfr_float_backend& operator=(const gmp_int& val)
771 {
772 if(this->m_data[0]._mpfr_d == 0)
773 mpfr_init2(this->m_data, multiprecision::detail::digits10_2_2(digits10));
774 mpfr_set_z(this->m_data, val.data(), GMP_RNDN);
775 return *this;
776 }
777 mpfr_float_backend& operator=(const gmp_rational& val)
778 {
779 if(this->m_data[0]._mpfr_d == 0)
780 mpfr_init2(this->m_data, multiprecision::detail::digits10_2_2(digits10));
781 mpfr_set_q(this->m_data, val.data(), GMP_RNDN);
782 return *this;
783 }
784};
785
786template <>
787struct mpfr_float_backend<0, allocate_dynamic> : public detail::mpfr_float_imp<0, allocate_dynamic>
788{
789 mpfr_float_backend() : detail::mpfr_float_imp<0, allocate_dynamic>() {}
790 mpfr_float_backend(const mpfr_t val)
791 : detail::mpfr_float_imp<0, allocate_dynamic>(mpfr_get_prec(val))
792 {
793 mpfr_set(this->m_data, val, GMP_RNDN);
794 }
795 mpfr_float_backend(const mpf_t val)
796 : detail::mpfr_float_imp<0, allocate_dynamic>(mpf_get_prec(val))
797 {
798 mpfr_set_f(this->m_data, val, GMP_RNDN);
799 }
800 mpfr_float_backend(const mpz_t val)
801 : detail::mpfr_float_imp<0, allocate_dynamic>()
802 {
803 mpfr_set_z(this->m_data, val, GMP_RNDN);
804 }
805 mpfr_float_backend(const mpq_t val)
806 : detail::mpfr_float_imp<0, allocate_dynamic>()
807 {
808 mpfr_set_q(this->m_data, val, GMP_RNDN);
809 }
810 mpfr_float_backend(const mpfr_float_backend& o) : detail::mpfr_float_imp<0, allocate_dynamic>(o) {}
811#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
812 mpfr_float_backend(mpfr_float_backend&& o) BOOST_NOEXCEPT : detail::mpfr_float_imp<0, allocate_dynamic>(static_cast<detail::mpfr_float_imp<0, allocate_dynamic>&&>(o)) {}
813#endif
814 mpfr_float_backend(const mpfr_float_backend& o, unsigned digits10)
815 : detail::mpfr_float_imp<0, allocate_dynamic>(digits10)
816 {
817 *this = o;
818 }
819 template <unsigned D>
820 mpfr_float_backend(const mpfr_float_backend<D>& val)
821 : detail::mpfr_float_imp<0, allocate_dynamic>(mpfr_get_prec(val.data()))
822 {
823 mpfr_set(this->m_data, val.data(), GMP_RNDN);
824 }
825 template <unsigned D>
826 mpfr_float_backend(const gmp_float<D>& val)
827 : detail::mpfr_float_imp<0, allocate_dynamic>(mpf_get_prec(val.data()))
828 {
829 mpfr_set_f(this->m_data, val.data(), GMP_RNDN);
830 }
831 mpfr_float_backend(const gmp_int& val)
832 : detail::mpfr_float_imp<0, allocate_dynamic>()
833 {
834 mpfr_set_z(this->m_data, val.data(), GMP_RNDN);
835 }
836 mpfr_float_backend(const gmp_rational& val)
837 : detail::mpfr_float_imp<0, allocate_dynamic>()
838 {
839 mpfr_set_q(this->m_data, val.data(), GMP_RNDN);
840 }
841
842 mpfr_float_backend& operator=(const mpfr_float_backend& o)
843 {
844 if(this != &o)
845 {
846 if(this->m_data[0]._mpfr_d == 0)
847 mpfr_init2(this->m_data, mpfr_get_prec(o.data()));
848 else
849 mpfr_set_prec(this->m_data, mpfr_get_prec(o.data()));
850 mpfr_set(this->m_data, o.data(), GMP_RNDN);
851 }
852 return *this;
853 }
854#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
855 mpfr_float_backend& operator=(mpfr_float_backend&& o) BOOST_NOEXCEPT
856 {
857 *static_cast<detail::mpfr_float_imp<0, allocate_dynamic>*>(this) = static_cast<detail::mpfr_float_imp<0, allocate_dynamic> &&>(o);
858 return *this;
859 }
860#endif
861 template <class V>
862 mpfr_float_backend& operator=(const V& v)
863 {
864 *static_cast<detail::mpfr_float_imp<0, allocate_dynamic>*>(this) = v;
865 return *this;
866 }
867 mpfr_float_backend& operator=(const mpfr_t val)
868 {
869 if(this->m_data[0]._mpfr_d == 0)
870 mpfr_init2(this->m_data, mpfr_get_prec(val));
871 else
872 mpfr_set_prec(this->m_data, mpfr_get_prec(val));
873 mpfr_set(this->m_data, val, GMP_RNDN);
874 return *this;
875 }
876 mpfr_float_backend& operator=(const mpf_t val)
877 {
878 if(this->m_data[0]._mpfr_d == 0)
879 mpfr_init2(this->m_data, mpf_get_prec(val));
880 else
881 mpfr_set_prec(this->m_data, mpf_get_prec(val));
882 mpfr_set_f(this->m_data, val, GMP_RNDN);
883 return *this;
884 }
885 mpfr_float_backend& operator=(const mpz_t val)
886 {
887 if(this->m_data[0]._mpfr_d == 0)
888 mpfr_init2(this->m_data, multiprecision::detail::digits10_2_2(get_default_precision()));
889 mpfr_set_z(this->m_data, val, GMP_RNDN);
890 return *this;
891 }
892 mpfr_float_backend& operator=(const mpq_t val)
893 {
894 if(this->m_data[0]._mpfr_d == 0)
895 mpfr_init2(this->m_data, multiprecision::detail::digits10_2_2(get_default_precision()));
896 mpfr_set_q(this->m_data, val, GMP_RNDN);
897 return *this;
898 }
899 template <unsigned D>
900 mpfr_float_backend& operator=(const mpfr_float_backend<D>& val)
901 {
902 if(this->m_data[0]._mpfr_d == 0)
903 mpfr_init2(this->m_data, mpfr_get_prec(val.data()));
904 else
905 mpfr_set_prec(this->m_data, mpfr_get_prec(val.data()));
906 mpfr_set(this->m_data, val.data(), GMP_RNDN);
907 return *this;
908 }
909 template <unsigned D>
910 mpfr_float_backend& operator=(const gmp_float<D>& val)
911 {
912 if(this->m_data[0]._mpfr_d == 0)
913 mpfr_init2(this->m_data, mpf_get_prec(val.data()));
914 else
915 mpfr_set_prec(this->m_data, mpf_get_prec(val.data()));
916 mpfr_set_f(this->m_data, val.data(), GMP_RNDN);
917 return *this;
918 }
919 mpfr_float_backend& operator=(const gmp_int& val)
920 {
921 if(this->m_data[0]._mpfr_d == 0)
922 mpfr_init2(this->m_data, multiprecision::detail::digits10_2_2(get_default_precision()));
923 mpfr_set_z(this->m_data, val.data(), GMP_RNDN);
924 return *this;
925 }
926 mpfr_float_backend& operator=(const gmp_rational& val)
927 {
928 if(this->m_data[0]._mpfr_d == 0)
929 mpfr_init2(this->m_data, multiprecision::detail::digits10_2_2(get_default_precision()));
930 mpfr_set_q(this->m_data, val.data(), GMP_RNDN);
931 return *this;
932 }
933 static unsigned default_precision() BOOST_NOEXCEPT
934 {
935 return get_default_precision();
936 }
937 static void default_precision(unsigned v) BOOST_NOEXCEPT
938 {
939 get_default_precision() = v;
940 }
941 unsigned precision()const BOOST_NOEXCEPT
942 {
943 return multiprecision::detail::digits2_2_10(mpfr_get_prec(this->m_data));
944 }
945 void precision(unsigned digits10) BOOST_NOEXCEPT
946 {
947 mpfr_prec_round(this->m_data, multiprecision::detail::digits10_2_2((digits10)), GMP_RNDN);
948 }
949};
950
951template <unsigned digits10, mpfr_allocation_type AllocationType, class T>
952inline typename enable_if<is_arithmetic<T>, bool>::type eval_eq(const mpfr_float_backend<digits10, AllocationType>& a, const T& b) BOOST_NOEXCEPT
953{
954 return a.compare(b) == 0;
955}
956template <unsigned digits10, mpfr_allocation_type AllocationType, class T>
957inline typename enable_if<is_arithmetic<T>, bool>::type eval_lt(const mpfr_float_backend<digits10, AllocationType>& a, const T& b) BOOST_NOEXCEPT
958{
959 return a.compare(b) < 0;
960}
961template <unsigned digits10, mpfr_allocation_type AllocationType, class T>
962inline typename enable_if<is_arithmetic<T>, bool>::type eval_gt(const mpfr_float_backend<digits10, AllocationType>& a, const T& b) BOOST_NOEXCEPT
963{
964 return a.compare(b) > 0;
965}
966
967template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2>
968inline void eval_add(mpfr_float_backend<D1, A1>& result, const mpfr_float_backend<D2, A2>& o)
969{
970 mpfr_add(result.data(), result.data(), o.data(), GMP_RNDN);
971}
972template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2>
973inline void eval_subtract(mpfr_float_backend<D1, A1>& result, const mpfr_float_backend<D2, A2>& o)
974{
975 mpfr_sub(result.data(), result.data(), o.data(), GMP_RNDN);
976}
977template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2>
978inline void eval_multiply(mpfr_float_backend<D1, A1>& result, const mpfr_float_backend<D2, A2>& o)
979{
980 if((void*)&o == (void*)&result)
981 mpfr_sqr(result.data(), o.data(), GMP_RNDN);
982 else
983 mpfr_mul(result.data(), result.data(), o.data(), GMP_RNDN);
984}
985template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2>
986inline void eval_divide(mpfr_float_backend<D1, A1>& result, const mpfr_float_backend<D2, A2>& o)
987{
988 mpfr_div(result.data(), result.data(), o.data(), GMP_RNDN);
989}
990template <unsigned digits10, mpfr_allocation_type AllocationType>
991inline void eval_add(mpfr_float_backend<digits10, AllocationType>& result, unsigned long i)
992{
993 mpfr_add_ui(result.data(), result.data(), i, GMP_RNDN);
994}
995template <unsigned digits10, mpfr_allocation_type AllocationType>
996inline void eval_subtract(mpfr_float_backend<digits10, AllocationType>& result, unsigned long i)
997{
998 mpfr_sub_ui(result.data(), result.data(), i, GMP_RNDN);
999}
1000template <unsigned digits10, mpfr_allocation_type AllocationType>
1001inline void eval_multiply(mpfr_float_backend<digits10, AllocationType>& result, unsigned long i)
1002{
1003 mpfr_mul_ui(result.data(), result.data(), i, GMP_RNDN);
1004}
1005template <unsigned digits10, mpfr_allocation_type AllocationType>
1006inline void eval_divide(mpfr_float_backend<digits10, AllocationType>& result, unsigned long i)
1007{
1008 mpfr_div_ui(result.data(), result.data(), i, GMP_RNDN);
1009}
1010template <unsigned digits10, mpfr_allocation_type AllocationType>
1011inline void eval_add(mpfr_float_backend<digits10, AllocationType>& result, long i)
1012{
1013 if(i > 0)
1014 mpfr_add_ui(result.data(), result.data(), i, GMP_RNDN);
1015 else
1016 mpfr_sub_ui(result.data(), result.data(), boost::multiprecision::detail::unsigned_abs(i), GMP_RNDN);
1017}
1018template <unsigned digits10, mpfr_allocation_type AllocationType>
1019inline void eval_subtract(mpfr_float_backend<digits10, AllocationType>& result, long i)
1020{
1021 if(i > 0)
1022 mpfr_sub_ui(result.data(), result.data(), i, GMP_RNDN);
1023 else
1024 mpfr_add_ui(result.data(), result.data(), boost::multiprecision::detail::unsigned_abs(i), GMP_RNDN);
1025}
1026template <unsigned digits10, mpfr_allocation_type AllocationType>
1027inline void eval_multiply(mpfr_float_backend<digits10, AllocationType>& result, long i)
1028{
1029 mpfr_mul_ui(result.data(), result.data(), boost::multiprecision::detail::unsigned_abs(i), GMP_RNDN);
1030 if(i < 0)
1031 mpfr_neg(result.data(), result.data(), GMP_RNDN);
1032}
1033template <unsigned digits10, mpfr_allocation_type AllocationType>
1034inline void eval_divide(mpfr_float_backend<digits10, AllocationType>& result, long i)
1035{
1036 mpfr_div_ui(result.data(), result.data(), boost::multiprecision::detail::unsigned_abs(i), GMP_RNDN);
1037 if(i < 0)
1038 mpfr_neg(result.data(), result.data(), GMP_RNDN);
1039}
1040//
1041// Specialised 3 arg versions of the basic operators:
1042//
1043template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2, unsigned D3>
1044inline void eval_add(mpfr_float_backend<D1, A1>& a, const mpfr_float_backend<D2, A2>& x, const mpfr_float_backend<D3>& y)
1045{
1046 mpfr_add(a.data(), x.data(), y.data(), GMP_RNDN);
1047}
1048template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2>
1049inline void eval_add(mpfr_float_backend<D1, A1>& a, const mpfr_float_backend<D2, A2>& x, unsigned long y)
1050{
1051 mpfr_add_ui(a.data(), x.data(), y, GMP_RNDN);
1052}
1053template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2>
1054inline void eval_add(mpfr_float_backend<D1, A1>& a, const mpfr_float_backend<D2, A2>& x, long y)
1055{
1056 if(y < 0)
1057 mpfr_sub_ui(a.data(), x.data(), boost::multiprecision::detail::unsigned_abs(y), GMP_RNDN);
1058 else
1059 mpfr_add_ui(a.data(), x.data(), y, GMP_RNDN);
1060}
1061template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2>
1062inline void eval_add(mpfr_float_backend<D1, A1>& a, unsigned long x, const mpfr_float_backend<D2, A2>& y)
1063{
1064 mpfr_add_ui(a.data(), y.data(), x, GMP_RNDN);
1065}
1066template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2>
1067inline void eval_add(mpfr_float_backend<D1, A1>& a, long x, const mpfr_float_backend<D2, A2>& y)
1068{
1069 if(x < 0)
1070 {
1071 mpfr_ui_sub(a.data(), boost::multiprecision::detail::unsigned_abs(x), y.data(), GMP_RNDN);
1072 mpfr_neg(a.data(), a.data(), GMP_RNDN);
1073 }
1074 else
1075 mpfr_add_ui(a.data(), y.data(), x, GMP_RNDN);
1076}
1077template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2, unsigned D3>
1078inline void eval_subtract(mpfr_float_backend<D1, A1>& a, const mpfr_float_backend<D2, A2>& x, const mpfr_float_backend<D3>& y)
1079{
1080 mpfr_sub(a.data(), x.data(), y.data(), GMP_RNDN);
1081}
1082template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2>
1083inline void eval_subtract(mpfr_float_backend<D1, A1>& a, const mpfr_float_backend<D2, A2>& x, unsigned long y)
1084{
1085 mpfr_sub_ui(a.data(), x.data(), y, GMP_RNDN);
1086}
1087template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2>
1088inline void eval_subtract(mpfr_float_backend<D1, A1>& a, const mpfr_float_backend<D2, A2>& x, long y)
1089{
1090 if(y < 0)
1091 mpfr_add_ui(a.data(), x.data(), boost::multiprecision::detail::unsigned_abs(y), GMP_RNDN);
1092 else
1093 mpfr_sub_ui(a.data(), x.data(), y, GMP_RNDN);
1094}
1095template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2>
1096inline void eval_subtract(mpfr_float_backend<D1, A1>& a, unsigned long x, const mpfr_float_backend<D2, A2>& y)
1097{
1098 mpfr_ui_sub(a.data(), x, y.data(), GMP_RNDN);
1099}
1100template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2>
1101inline void eval_subtract(mpfr_float_backend<D1, A1>& a, long x, const mpfr_float_backend<D2, A2>& y)
1102{
1103 if(x < 0)
1104 {
1105 mpfr_add_ui(a.data(), y.data(), boost::multiprecision::detail::unsigned_abs(x), GMP_RNDN);
1106 mpfr_neg(a.data(), a.data(), GMP_RNDN);
1107 }
1108 else
1109 mpfr_ui_sub(a.data(), x, y.data(), GMP_RNDN);
1110}
1111
1112template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2, unsigned D3>
1113inline void eval_multiply(mpfr_float_backend<D1, A1>& a, const mpfr_float_backend<D2, A2>& x, const mpfr_float_backend<D3>& y)
1114{
1115 if((void*)&x == (void*)&y)
1116 mpfr_sqr(a.data(), x.data(), GMP_RNDN);
1117 else
1118 mpfr_mul(a.data(), x.data(), y.data(), GMP_RNDN);
1119}
1120template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2>
1121inline void eval_multiply(mpfr_float_backend<D1, A1>& a, const mpfr_float_backend<D2, A2>& x, unsigned long y)
1122{
1123 mpfr_mul_ui(a.data(), x.data(), y, GMP_RNDN);
1124}
1125template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2>
1126inline void eval_multiply(mpfr_float_backend<D1, A1>& a, const mpfr_float_backend<D2, A2>& x, long y)
1127{
1128 if(y < 0)
1129 {
1130 mpfr_mul_ui(a.data(), x.data(), boost::multiprecision::detail::unsigned_abs(y), GMP_RNDN);
1131 a.negate();
1132 }
1133 else
1134 mpfr_mul_ui(a.data(), x.data(), y, GMP_RNDN);
1135}
1136template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2>
1137inline void eval_multiply(mpfr_float_backend<D1, A1>& a, unsigned long x, const mpfr_float_backend<D2, A2>& y)
1138{
1139 mpfr_mul_ui(a.data(), y.data(), x, GMP_RNDN);
1140}
1141template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2>
1142inline void eval_multiply(mpfr_float_backend<D1, A1>& a, long x, const mpfr_float_backend<D2, A2>& y)
1143{
1144 if(x < 0)
1145 {
1146 mpfr_mul_ui(a.data(), y.data(), boost::multiprecision::detail::unsigned_abs(x), GMP_RNDN);
1147 mpfr_neg(a.data(), a.data(), GMP_RNDN);
1148 }
1149 else
1150 mpfr_mul_ui(a.data(), y.data(), x, GMP_RNDN);
1151}
1152
1153template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2, unsigned D3>
1154inline void eval_divide(mpfr_float_backend<D1, A1>& a, const mpfr_float_backend<D2, A2>& x, const mpfr_float_backend<D3>& y)
1155{
1156 mpfr_div(a.data(), x.data(), y.data(), GMP_RNDN);
1157}
1158template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2>
1159inline void eval_divide(mpfr_float_backend<D1, A1>& a, const mpfr_float_backend<D2, A2>& x, unsigned long y)
1160{
1161 mpfr_div_ui(a.data(), x.data(), y, GMP_RNDN);
1162}
1163template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2>
1164inline void eval_divide(mpfr_float_backend<D1, A1>& a, const mpfr_float_backend<D2, A2>& x, long y)
1165{
1166 if(y < 0)
1167 {
1168 mpfr_div_ui(a.data(), x.data(), boost::multiprecision::detail::unsigned_abs(y), GMP_RNDN);
1169 a.negate();
1170 }
1171 else
1172 mpfr_div_ui(a.data(), x.data(), y, GMP_RNDN);
1173}
1174template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2>
1175inline void eval_divide(mpfr_float_backend<D1, A1>& a, unsigned long x, const mpfr_float_backend<D2, A2>& y)
1176{
1177 mpfr_ui_div(a.data(), x, y.data(), GMP_RNDN);
1178}
1179template <unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2>
1180inline void eval_divide(mpfr_float_backend<D1, A1>& a, long x, const mpfr_float_backend<D2, A2>& y)
1181{
1182 if(x < 0)
1183 {
1184 mpfr_ui_div(a.data(), boost::multiprecision::detail::unsigned_abs(x), y.data(), GMP_RNDN);
1185 mpfr_neg(a.data(), a.data(), GMP_RNDN);
1186 }
1187 else
1188 mpfr_ui_div(a.data(), x, y.data(), GMP_RNDN);
1189}
1190
1191template <unsigned digits10, mpfr_allocation_type AllocationType>
1192inline bool eval_is_zero(const mpfr_float_backend<digits10, AllocationType>& val) BOOST_NOEXCEPT
1193{
1194 return 0 != mpfr_zero_p(val.data());
1195}
1196template <unsigned digits10, mpfr_allocation_type AllocationType>
1197inline int eval_get_sign(const mpfr_float_backend<digits10, AllocationType>& val) BOOST_NOEXCEPT
1198{
1199 return mpfr_sgn(val.data());
1200}
1201
1202template <unsigned digits10, mpfr_allocation_type AllocationType>
1203inline void eval_convert_to(unsigned long* result, const mpfr_float_backend<digits10, AllocationType>& val)
1204{
1205 if(mpfr_nan_p(val.data()))
1206 {
1207 BOOST_THROW_EXCEPTION(std::runtime_error("Could not convert NaN to integer."));
1208 }
1209 *result = mpfr_get_ui(val.data(), GMP_RNDZ);
1210}
1211template <unsigned digits10, mpfr_allocation_type AllocationType>
1212inline void eval_convert_to(long* result, const mpfr_float_backend<digits10, AllocationType>& val)
1213{
1214 if(mpfr_nan_p(val.data()))
1215 {
1216 BOOST_THROW_EXCEPTION(std::runtime_error("Could not convert NaN to integer."));
1217 }
1218 *result = mpfr_get_si(val.data(), GMP_RNDZ);
1219}
1220#ifdef _MPFR_H_HAVE_INTMAX_T
1221template <unsigned digits10, mpfr_allocation_type AllocationType>
1222inline void eval_convert_to(boost::ulong_long_type* result, const mpfr_float_backend<digits10, AllocationType>& val)
1223{
1224 if(mpfr_nan_p(val.data()))
1225 {
1226 BOOST_THROW_EXCEPTION(std::runtime_error("Could not convert NaN to integer."));
1227 }
1228 *result = mpfr_get_uj(val.data(), GMP_RNDZ);
1229}
1230template <unsigned digits10, mpfr_allocation_type AllocationType>
1231inline void eval_convert_to(boost::long_long_type* result, const mpfr_float_backend<digits10, AllocationType>& val)
1232{
1233 if(mpfr_nan_p(val.data()))
1234 {
1235 BOOST_THROW_EXCEPTION(std::runtime_error("Could not convert NaN to integer."));
1236 }
1237 *result = mpfr_get_sj(val.data(), GMP_RNDZ);
1238}
1239#endif
1240template <unsigned digits10, mpfr_allocation_type AllocationType>
1241inline void eval_convert_to(float* result, const mpfr_float_backend<digits10, AllocationType>& val) BOOST_NOEXCEPT
1242{
1243 *result = mpfr_get_flt(val.data(), GMP_RNDN);
1244}
1245template <unsigned digits10, mpfr_allocation_type AllocationType>
1246inline void eval_convert_to(double* result, const mpfr_float_backend<digits10, AllocationType>& val) BOOST_NOEXCEPT
1247{
1248 *result = mpfr_get_d(val.data(), GMP_RNDN);
1249}
1250template <unsigned digits10, mpfr_allocation_type AllocationType>
1251inline void eval_convert_to(long double* result, const mpfr_float_backend<digits10, AllocationType>& val) BOOST_NOEXCEPT
1252{
1253 *result = mpfr_get_ld(val.data(), GMP_RNDN);
1254}
1255
1256//
1257// Native non-member operations:
1258//
1259template <unsigned Digits10, mpfr_allocation_type AllocateType>
1260inline void eval_sqrt(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& val)
1261{
1262 mpfr_sqrt(result.data(), val.data(), GMP_RNDN);
1263}
1264
1265template <unsigned Digits10, mpfr_allocation_type AllocateType>
1266inline void eval_abs(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& val)
1267{
1268 mpfr_abs(result.data(), val.data(), GMP_RNDN);
1269}
1270
1271template <unsigned Digits10, mpfr_allocation_type AllocateType>
1272inline void eval_fabs(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& val)
1273{
1274 mpfr_abs(result.data(), val.data(), GMP_RNDN);
1275}
1276template <unsigned Digits10, mpfr_allocation_type AllocateType>
1277inline void eval_ceil(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& val)
1278{
1279 mpfr_ceil(result.data(), val.data());
1280}
1281template <unsigned Digits10, mpfr_allocation_type AllocateType>
1282inline void eval_floor(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& val)
1283{
1284 mpfr_floor(result.data(), val.data());
1285}
1286template <unsigned Digits10, mpfr_allocation_type AllocateType>
1287inline void eval_trunc(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& val)
1288{
1289 if(0 == mpfr_number_p(val.data()))
1290 {
1291 result = boost::math::policies::raise_rounding_error("boost::multiprecision::trunc<%1%>(%1%)", 0, number<mpfr_float_backend<Digits10, AllocateType> >(val), number<mpfr_float_backend<Digits10, AllocateType> >(val), boost::math::policies::policy<>()).backend();
1292 return;
1293 }
1294 mpfr_trunc(result.data(), val.data());
1295}
1296template <unsigned Digits10, mpfr_allocation_type AllocateType>
1297inline void eval_ldexp(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& val, long e)
1298{
1299 if(e > 0)
1300 mpfr_mul_2exp(result.data(), val.data(), e, GMP_RNDN);
1301 else if(e < 0)
1302 mpfr_div_2exp(result.data(), val.data(), -e, GMP_RNDN);
1303 else
1304 result = val;
1305}
1306template <unsigned Digits10, mpfr_allocation_type AllocateType>
1307inline void eval_frexp(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& val, int* e)
1308{
1309 long v;
1310 mpfr_get_d_2exp(&v, val.data(), GMP_RNDN);
1311 *e = v;
1312 eval_ldexp(result, val, -v);
1313}
1314template <unsigned Digits10, mpfr_allocation_type AllocateType>
1315inline void eval_frexp(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& val, long* e)
1316{
1317 mpfr_get_d_2exp(e, val.data(), GMP_RNDN);
1318 return eval_ldexp(result, val, -*e);
1319}
1320
1321template <unsigned Digits10, mpfr_allocation_type AllocateType>
1322inline int eval_fpclassify(const mpfr_float_backend<Digits10, AllocateType>& val) BOOST_NOEXCEPT
1323{
1324 return mpfr_inf_p(val.data()) ? FP_INFINITE : mpfr_nan_p(val.data()) ? FP_NAN : mpfr_zero_p(val.data()) ? FP_ZERO : FP_NORMAL;
1325}
1326
1327template <unsigned Digits10, mpfr_allocation_type AllocateType>
1328inline void eval_pow(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& b, const mpfr_float_backend<Digits10, AllocateType>& e)
1329{
1330 mpfr_pow(result.data(), b.data(), e.data(), GMP_RNDN);
1331}
1332
1333#ifdef BOOST_MSVC
1334//
1335// The enable_if usage below doesn't work with msvc - but only when
1336// certain other enable_if usages are defined first. It's a capricious
1337// and rather annoying compiler bug in other words....
1338//
1339# define BOOST_MP_ENABLE_IF_WORKAROUND (Digits10 || !Digits10) &&
1340#else
1341#define BOOST_MP_ENABLE_IF_WORKAROUND
1342#endif
1343
1344template <unsigned Digits10, mpfr_allocation_type AllocateType, class Integer>
1345inline typename enable_if<mpl::and_<is_signed<Integer>, mpl::bool_<BOOST_MP_ENABLE_IF_WORKAROUND (sizeof(Integer) <= sizeof(long))> > >::type
1346 eval_pow(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& b, const Integer& e)
1347{
1348 mpfr_pow_si(result.data(), b.data(), e, GMP_RNDN);
1349}
1350
1351template <unsigned Digits10, mpfr_allocation_type AllocateType, class Integer>
1352inline typename enable_if<mpl::and_<is_unsigned<Integer>, mpl::bool_<BOOST_MP_ENABLE_IF_WORKAROUND (sizeof(Integer) <= sizeof(long))> > >::type
1353 eval_pow(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& b, const Integer& e)
1354{
1355 mpfr_pow_ui(result.data(), b.data(), e, GMP_RNDN);
1356}
1357
1358#undef BOOST_MP_ENABLE_IF_WORKAROUND
1359
1360template <unsigned Digits10, mpfr_allocation_type AllocateType>
1361inline void eval_exp(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& arg)
1362{
1363 mpfr_exp(result.data(), arg.data(), GMP_RNDN);
1364}
1365
1366template <unsigned Digits10, mpfr_allocation_type AllocateType>
1367inline void eval_exp2(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& arg)
1368{
1369 mpfr_exp2(result.data(), arg.data(), GMP_RNDN);
1370}
1371
1372template <unsigned Digits10, mpfr_allocation_type AllocateType>
1373inline void eval_log(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& arg)
1374{
1375 mpfr_log(result.data(), arg.data(), GMP_RNDN);
1376}
1377
1378template <unsigned Digits10, mpfr_allocation_type AllocateType>
1379inline void eval_log10(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& arg)
1380{
1381 mpfr_log10(result.data(), arg.data(), GMP_RNDN);
1382}
1383
1384template <unsigned Digits10, mpfr_allocation_type AllocateType>
1385inline void eval_sin(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& arg)
1386{
1387 mpfr_sin(result.data(), arg.data(), GMP_RNDN);
1388}
1389
1390template <unsigned Digits10, mpfr_allocation_type AllocateType>
1391inline void eval_cos(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& arg)
1392{
1393 mpfr_cos(result.data(), arg.data(), GMP_RNDN);
1394}
1395
1396template <unsigned Digits10, mpfr_allocation_type AllocateType>
1397inline void eval_tan(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& arg)
1398{
1399 mpfr_tan(result.data(), arg.data(), GMP_RNDN);
1400}
1401
1402template <unsigned Digits10, mpfr_allocation_type AllocateType>
1403inline void eval_asin(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& arg)
1404{
1405 mpfr_asin(result.data(), arg.data(), GMP_RNDN);
1406}
1407
1408template <unsigned Digits10, mpfr_allocation_type AllocateType>
1409inline void eval_acos(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& arg)
1410{
1411 mpfr_acos(result.data(), arg.data(), GMP_RNDN);
1412}
1413
1414template <unsigned Digits10, mpfr_allocation_type AllocateType>
1415inline void eval_atan(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& arg)
1416{
1417 mpfr_atan(result.data(), arg.data(), GMP_RNDN);
1418}
1419
1420template <unsigned Digits10, mpfr_allocation_type AllocateType>
1421inline void eval_atan2(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& arg1, const mpfr_float_backend<Digits10, AllocateType>& arg2)
1422{
1423 mpfr_atan2(result.data(), arg1.data(), arg2.data(), GMP_RNDN);
1424}
1425
1426template <unsigned Digits10, mpfr_allocation_type AllocateType>
1427inline void eval_sinh(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& arg)
1428{
1429 mpfr_sinh(result.data(), arg.data(), GMP_RNDN);
1430}
1431
1432template <unsigned Digits10, mpfr_allocation_type AllocateType>
1433inline void eval_cosh(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& arg)
1434{
1435 mpfr_cosh(result.data(), arg.data(), GMP_RNDN);
1436}
1437
1438template <unsigned Digits10, mpfr_allocation_type AllocateType>
1439inline void eval_tanh(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& arg)
1440{
1441 mpfr_tanh(result.data(), arg.data(), GMP_RNDN);
1442}
1443
1444template <unsigned Digits10, mpfr_allocation_type AllocateType>
1445inline void eval_log2(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& arg)
1446{
1447 mpfr_log2(result.data(), arg.data(), GMP_RNDN);
1448}
1449
1450template <unsigned Digits10, mpfr_allocation_type AllocateType>
1451inline void eval_modf(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& arg, mpfr_float_backend<Digits10, AllocateType>* pipart)
1452{
1453 if(0 == pipart)
1454 {
1455 mpfr_float_backend<Digits10, AllocateType> ipart;
1456 mpfr_modf(ipart.data(), result.data(), arg.data(), GMP_RNDN);
1457 }
1458 else
1459 {
1460 mpfr_modf(pipart->data(), result.data(), arg.data(), GMP_RNDN);
1461 }
1462}
1463template <unsigned Digits10, mpfr_allocation_type AllocateType>
1464inline void eval_remainder(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& a, const mpfr_float_backend<Digits10, AllocateType>& b)
1465{
1466 mpfr_remainder(result.data(), a.data(), b.data(), GMP_RNDN);
1467}
1468template <unsigned Digits10, mpfr_allocation_type AllocateType>
1469inline void eval_remquo(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& a, const mpfr_float_backend<Digits10, AllocateType>& b, int* pi)
1470{
1471 long l;
1472 mpfr_remquo(result.data(), &l, a.data(), b.data(), GMP_RNDN);
1473 if(pi) *pi = l;
1474}
1475
1476template <unsigned Digits10, mpfr_allocation_type AllocateType>
1477inline void eval_fmod(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& a, const mpfr_float_backend<Digits10, AllocateType>& b)
1478{
1479 mpfr_fmod(result.data(), a.data(), b.data(), GMP_RNDN);
1480}
1481
1482template <unsigned Digits10, mpfr_allocation_type AllocateType>
1483inline void eval_multiply_add(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& a, const mpfr_float_backend<Digits10, AllocateType>& b)
1484{
1485 mpfr_fma(result.data(), a.data(), b.data(), result.data(), GMP_RNDN);
1486}
1487
1488template <unsigned Digits10, mpfr_allocation_type AllocateType>
1489inline void eval_multiply_add(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& a, const mpfr_float_backend<Digits10, AllocateType>& b, const mpfr_float_backend<Digits10, AllocateType>& c)
1490{
1491 mpfr_fma(result.data(), a.data(), b.data(), c.data(), GMP_RNDN);
1492}
1493
1494template <unsigned Digits10, mpfr_allocation_type AllocateType>
1495inline void eval_multiply_subtract(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& a, const mpfr_float_backend<Digits10, AllocateType>& b)
1496{
1497 mpfr_fms(result.data(), a.data(), b.data(), result.data(), GMP_RNDN);
1498 result.negate();
1499}
1500
1501template <unsigned Digits10, mpfr_allocation_type AllocateType>
1502inline void eval_multiply_subtract(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& a, const mpfr_float_backend<Digits10, AllocateType>& b, const mpfr_float_backend<Digits10, AllocateType>& c)
1503{
1504 mpfr_fms(result.data(), a.data(), b.data(), c.data(), GMP_RNDN);
1505}
1506
1507template <unsigned Digits10, mpfr_allocation_type AllocateType>
1508inline std::size_t hash_value(const mpfr_float_backend<Digits10, AllocateType>& val)
1509{
1510 std::size_t result = 0;
1511 std::size_t len = val.data()[0]._mpfr_prec / mp_bits_per_limb;
1512 if(val.data()[0]._mpfr_prec % mp_bits_per_limb)
1513 ++len;
1514 for(int i = 0; i < len; ++i)
1515 boost::hash_combine(result, val.data()[0]._mpfr_d[i]);
1516 boost::hash_combine(result, val.data()[0]._mpfr_exp);
1517 boost::hash_combine(result, val.data()[0]._mpfr_sign);
1518 return result;
1519}
1520
1521} // namespace backends
1522
1523#ifdef BOOST_NO_SFINAE_EXPR
1524
1525namespace detail{
1526
1527template<unsigned D1, unsigned D2, mpfr_allocation_type A1, mpfr_allocation_type A2>
1528struct is_explicitly_convertible<backends::mpfr_float_backend<D1, A1>, backends::mpfr_float_backend<D2, A2> > : public mpl::true_ {};
1529
1530}
1531
1532#endif
1533
1534template<>
1535struct number_category<detail::canonical<mpfr_t, backends::mpfr_float_backend<0> >::type> : public mpl::int_<number_kind_floating_point>{};
1536
1537using boost::multiprecision::backends::mpfr_float_backend;
1538
1539typedef number<mpfr_float_backend<50> > mpfr_float_50;
1540typedef number<mpfr_float_backend<100> > mpfr_float_100;
1541typedef number<mpfr_float_backend<500> > mpfr_float_500;
1542typedef number<mpfr_float_backend<1000> > mpfr_float_1000;
1543typedef number<mpfr_float_backend<0> > mpfr_float;
1544
1545typedef number<mpfr_float_backend<50, allocate_stack> > static_mpfr_float_50;
1546typedef number<mpfr_float_backend<100, allocate_stack> > static_mpfr_float_100;
1547
1548template<unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
1549inline int signbit BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>& arg)
1550{
1551 return (arg.backend().data()[0]._mpfr_sign < 0) ? 1 : 0;
1552}
1553
1554template<unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
1555inline boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> copysign BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>& a, const boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>& b)
1556{
1557 return (boost::multiprecision::signbit)(a) != (boost::multiprecision::signbit)(b) ? boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>(-a) : a;
1558}
1559
1560template<unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
1561inline int signbit BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>& arg)
1562{
1563 return (arg.backend().value().data()[0]._mpfr_sign < 0) ? 1 : 0;
1564}
1565
1566template<unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
1567inline boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> copysign BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>& a, const boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>& b)
1568{
1569 return (boost::multiprecision::signbit)(a) != (boost::multiprecision::signbit)(b) ? boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates>(-a) : a;
1570}
1571
1572} // namespace multiprecision
1573
1574namespace math{
1575
1576 using boost::multiprecision::signbit;
1577 using boost::multiprecision::copysign;
1578
1579namespace tools{
1580
1581template <>
1582inline int digits<boost::multiprecision::mpfr_float>()
1583#ifdef BOOST_MATH_NOEXCEPT
1584 BOOST_NOEXCEPT
1585#endif
1586{
1587 return multiprecision::detail::digits10_2_2(boost::multiprecision::mpfr_float::default_precision());
1588}
1589template <>
1590inline int digits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, boost::multiprecision::et_off> >()
1591#ifdef BOOST_MATH_NOEXCEPT
1592 BOOST_NOEXCEPT
1593#endif
1594{
1595 return multiprecision::detail::digits10_2_2(boost::multiprecision::mpfr_float::default_precision());
1596}
1597
1598template <>
1599inline boost::multiprecision::mpfr_float
1600 max_value<boost::multiprecision::mpfr_float>()
1601{
1602 boost::multiprecision::mpfr_float result(0.5);
1603 mpfr_mul_2exp(result.backend().data(), result.backend().data(), mpfr_get_emax(), GMP_RNDN);
1604 BOOST_ASSERT(mpfr_number_p(result.backend().data()));
1605 return result;
1606}
1607
1608template <>
1609inline boost::multiprecision::mpfr_float
1610 min_value<boost::multiprecision::mpfr_float>()
1611{
1612 boost::multiprecision::mpfr_float result(0.5);
1613 mpfr_div_2exp(result.backend().data(), result.backend().data(), -mpfr_get_emin(), GMP_RNDN);
1614 BOOST_ASSERT(mpfr_number_p(result.backend().data()));
1615 return result;
1616}
1617
1618template <>
1619inline boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, boost::multiprecision::et_off>
1620 max_value<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, boost::multiprecision::et_off> >()
1621{
1622 boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, boost::multiprecision::et_off> result(0.5);
1623 mpfr_mul_2exp(result.backend().data(), result.backend().data(), mpfr_get_emax(), GMP_RNDN);
1624 BOOST_ASSERT(mpfr_number_p(result.backend().data()));
1625 return result;
1626}
1627
1628template <>
1629inline boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, boost::multiprecision::et_off>
1630 min_value<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, boost::multiprecision::et_off> >()
1631{
1632 boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, boost::multiprecision::et_off> result(0.5);
1633 mpfr_div_2exp(result.backend().data(), result.backend().data(), -mpfr_get_emin(), GMP_RNDN);
1634 BOOST_ASSERT(mpfr_number_p(result.backend().data()));
1635 return result;
1636}
1637
1638template <>
1639inline int digits<boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float::backend_type> > >()
1640#ifdef BOOST_MATH_NOEXCEPT
1641BOOST_NOEXCEPT
1642#endif
1643{
1644 return multiprecision::detail::digits10_2_2(boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float::backend_type> >::default_precision());
1645}
1646template <>
1647inline int digits<boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<0> >, boost::multiprecision::et_off> >()
1648#ifdef BOOST_MATH_NOEXCEPT
1649BOOST_NOEXCEPT
1650#endif
1651{
1652 return multiprecision::detail::digits10_2_2(boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float::backend_type> >::default_precision());
1653}
1654
1655template <>
1656inline boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float::backend_type> >
1657max_value<boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float::backend_type> > >()
1658{
1659 return max_value<boost::multiprecision::mpfr_float>().backend();
1660}
1661
1662template <>
1663inline boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float::backend_type> >
1664min_value<boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float::backend_type> > >()
1665{
1666 return min_value<boost::multiprecision::mpfr_float>().backend();
1667}
1668
1669template <>
1670inline boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<0> >, boost::multiprecision::et_off>
1671max_value<boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<0> >, boost::multiprecision::et_off> >()
1672{
1673 return max_value<boost::multiprecision::mpfr_float>().backend();
1674}
1675
1676template <>
1677inline boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<0> >, boost::multiprecision::et_off>
1678min_value<boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<0> >, boost::multiprecision::et_off> >()
1679{
1680 return min_value<boost::multiprecision::mpfr_float>().backend();
1681}
1682
1683} // namespace tools
1684
1685namespace constants{ namespace detail{
1686
1687template <class T> struct constant_pi;
1688template <class T> struct constant_ln_two;
1689template <class T> struct constant_euler;
1690template <class T> struct constant_catalan;
1691
1692namespace detail{
1693
1694 template <class T, int N>
1695 struct mpfr_constant_initializer
1696 {
1697 static void force_instantiate()
1698 {
1699 init.force_instantiate();
1700 }
1701 private:
1702 struct initializer
1703 {
1704 initializer()
1705 {
1706 T::get(mpl::int_<N>());
1707 }
1708 void force_instantiate()const{}
1709 };
1710 static const initializer init;
1711 };
1712
1713 template <class T, int N>
1714 typename mpfr_constant_initializer<T, N>::initializer const mpfr_constant_initializer<T, N>::init;
1715
1716}
1717
1718template<unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
1719struct constant_pi<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >
1720{
1721 typedef boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> result_type;
1722 template<int N>
1723 static inline const result_type& get(const mpl::int_<N>&)
1724 {
1725 detail::mpfr_constant_initializer<constant_pi<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >, N>::force_instantiate();
1726 static result_type result;
1727 static bool has_init = false;
1728 if(!has_init)
1729 {
1730 mpfr_const_pi(result.backend().data(), GMP_RNDN);
1731 has_init = true;
1732 }
1733 return result;
1734 }
1735 static inline const result_type get(const mpl::int_<0>&)
1736 {
1737 result_type result;
1738 mpfr_const_pi(result.backend().data(), GMP_RNDN);
1739 return result;
1740 }
1741};
1742template<unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
1743struct constant_ln_two<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >
1744{
1745 typedef boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> result_type;
1746 template<int N>
1747 static inline const result_type& get(const mpl::int_<N>&)
1748 {
1749 detail::mpfr_constant_initializer<constant_ln_two<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >, N>::force_instantiate();
1750 static result_type result;
1751 static bool init = false;
1752 if(!init)
1753 {
1754 mpfr_const_log2(result.backend().data(), GMP_RNDN);
1755 init = true;
1756 }
1757 return result;
1758 }
1759 static inline const result_type get(const mpl::int_<0>&)
1760 {
1761 result_type result;
1762 mpfr_const_log2(result.backend().data(), GMP_RNDN);
1763 return result;
1764 }
1765};
1766template<unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
1767struct constant_euler<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >
1768{
1769 typedef boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> result_type;
1770 template<int N>
1771 static inline const result_type& get(const mpl::int_<N>&)
1772 {
1773 detail::mpfr_constant_initializer<constant_euler<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >, N>::force_instantiate();
1774 static result_type result;
1775 static bool init = false;
1776 if(!init)
1777 {
1778 mpfr_const_euler(result.backend().data(), GMP_RNDN);
1779 init = true;
1780 }
1781 return result;
1782 }
1783 static inline const result_type get(const mpl::int_<0>&)
1784 {
1785 result_type result;
1786 mpfr_const_euler(result.backend().data(), GMP_RNDN);
1787 return result;
1788 }
1789};
1790template<unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
1791struct constant_catalan<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >
1792{
1793 typedef boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> result_type;
1794 template<int N>
1795 static inline const result_type& get(const mpl::int_<N>&)
1796 {
1797 detail::mpfr_constant_initializer<constant_catalan<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >, N>::force_instantiate();
1798 static result_type result;
1799 static bool init = false;
1800 if(!init)
1801 {
1802 mpfr_const_catalan(result.backend().data(), GMP_RNDN);
1803 init = true;
1804 }
1805 return result;
1806 }
1807 static inline const result_type get(const mpl::int_<0>&)
1808 {
1809 result_type result;
1810 mpfr_const_catalan(result.backend().data(), GMP_RNDN);
1811 return result;
1812 }
1813};
1814
1815template<unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
1816struct constant_pi<boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> >
1817{
1818 typedef boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> result_type;
1819 template<int N>
1820 static inline const result_type& get(const mpl::int_<N>&)
1821 {
1822 detail::mpfr_constant_initializer<constant_pi<boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> >, N>::force_instantiate();
1823 static result_type result;
1824 static bool has_init = false;
1825 if(!has_init)
1826 {
1827 mpfr_const_pi(result.backend().value().data(), GMP_RNDN);
1828 has_init = true;
1829 }
1830 return result;
1831 }
1832 static inline const result_type get(const mpl::int_<0>&)
1833 {
1834 result_type result;
1835 mpfr_const_pi(result.backend().value().data(), GMP_RNDN);
1836 return result;
1837 }
1838};
1839template<unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
1840struct constant_ln_two<boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> >
1841{
1842 typedef boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> result_type;
1843 template<int N>
1844 static inline const result_type& get(const mpl::int_<N>&)
1845 {
1846 detail::mpfr_constant_initializer<constant_ln_two<boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> >, N>::force_instantiate();
1847 static result_type result;
1848 static bool init = false;
1849 if(!init)
1850 {
1851 mpfr_const_log2(result.backend().value().data(), GMP_RNDN);
1852 init = true;
1853 }
1854 return result;
1855 }
1856 static inline const result_type get(const mpl::int_<0>&)
1857 {
1858 result_type result;
1859 mpfr_const_log2(result.backend().value().data(), GMP_RNDN);
1860 return result;
1861 }
1862};
1863template<unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
1864struct constant_euler<boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> >
1865{
1866 typedef boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> result_type;
1867 template<int N>
1868 static inline const result_type& get(const mpl::int_<N>&)
1869 {
1870 detail::mpfr_constant_initializer<constant_euler<boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> >, N>::force_instantiate();
1871 static result_type result;
1872 static bool init = false;
1873 if(!init)
1874 {
1875 mpfr_const_euler(result.backend().value().data(), GMP_RNDN);
1876 init = true;
1877 }
1878 return result;
1879 }
1880 static inline const result_type get(const mpl::int_<0>&)
1881 {
1882 result_type result;
1883 mpfr_const_euler(result.backend().value().data(), GMP_RNDN);
1884 return result;
1885 }
1886};
1887template<unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
1888struct constant_catalan<boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> >
1889{
1890 typedef boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> result_type;
1891 template<int N>
1892 static inline const result_type& get(const mpl::int_<N>&)
1893 {
1894 detail::mpfr_constant_initializer<constant_catalan<boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> >, N>::force_instantiate();
1895 static result_type result;
1896 static bool init = false;
1897 if(!init)
1898 {
1899 mpfr_const_catalan(result.backend().value().data(), GMP_RNDN);
1900 init = true;
1901 }
1902 return result;
1903 }
1904 static inline const result_type get(const mpl::int_<0>&)
1905 {
1906 result_type result;
1907 mpfr_const_catalan(result.backend().value().data(), GMP_RNDN);
1908 return result;
1909 }
1910};
1911
1912}} // namespaces
1913
1914} // namespace multiprecision
1915
1916namespace multiprecision {
1917 //
1918 // Overloaded special functions which call native mpfr routines:
1919 //
1920 template<unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
1921 inline boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> asinh BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>& arg)
1922 {
1923 boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> result;
1924 mpfr_asinh(result.backend().data(), arg.backend().data(), GMP_RNDN);
1925 return BOOST_MP_MOVE(result);
1926 }
1927 template<unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
1928 inline boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> acosh BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>& arg)
1929 {
1930 boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> result;
1931 mpfr_acosh(result.backend().data(), arg.backend().data(), GMP_RNDN);
1932 return BOOST_MP_MOVE(result);
1933 }
1934 template<unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
1935 inline boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> atanh BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>& arg)
1936 {
1937 boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> result;
1938 mpfr_atanh(result.backend().data(), arg.backend().data(), GMP_RNDN);
1939 return BOOST_MP_MOVE(result);
1940 }
1941 template<unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
1942 inline boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> cbrt BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>& arg)
1943 {
1944 boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> result;
1945 mpfr_cbrt(result.backend().data(), arg.backend().data(), GMP_RNDN);
1946 return BOOST_MP_MOVE(result);
1947 }
1948 template<unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
1949 inline boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> erf BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>& arg)
1950 {
1951 boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> result;
1952 mpfr_erf(result.backend().data(), arg.backend().data(), GMP_RNDN);
1953 return BOOST_MP_MOVE(result);
1954 }
1955 template<unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
1956 inline boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> erfc BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>& arg)
1957 {
1958 boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> result;
1959 mpfr_erfc(result.backend().data(), arg.backend().data(), GMP_RNDN);
1960 return BOOST_MP_MOVE(result);
1961 }
1962 template<unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
1963 inline boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> expm1 BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>& arg)
1964 {
1965 boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> result;
1966 mpfr_expm1(result.backend().data(), arg.backend().data(), GMP_RNDN);
1967 return BOOST_MP_MOVE(result);
1968 }
1969 template<unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
1970 inline boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> lgamma BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>& arg)
1971 {
1972 boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> result;
1973 mpfr_lngamma(result.backend().data(), arg.backend().data(), GMP_RNDN);
1974 return BOOST_MP_MOVE(result);
1975 }
1976 template<unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
1977 inline boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> tgamma BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>& arg)
1978 {
1979 boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> result;
1980 mpfr_gamma(result.backend().data(), arg.backend().data(), GMP_RNDN);
1981 return BOOST_MP_MOVE(result);
1982 }
1983 template<unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
1984 inline boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> log1p BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>& arg)
1985 {
1986 boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> result;
1987 mpfr_log1p(result.backend().data(), arg.backend().data(), GMP_RNDN);
1988 return BOOST_MP_MOVE(result);
1989 }
1990
1991}
1992
1993} // namespace boost
1994
1995namespace std{
1996
1997//
1998// numeric_limits [partial] specializations for the types declared in this header:
1999//
2000template<unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2001class numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >
2002{
2003 typedef boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> number_type;
2004public:
2005 BOOST_STATIC_CONSTEXPR bool is_specialized = true;
2006 static number_type (min)()
2007 {
2008 initializer.do_nothing();
2009 static std::pair<bool, number_type> value;
2010 if(!value.first)
2011 {
2012 value.first = true;
2013 value.second = 0.5;
2014 mpfr_div_2exp(value.second.backend().data(), value.second.backend().data(), -mpfr_get_emin(), GMP_RNDN);
2015 }
2016 return value.second;
2017 }
2018 static number_type (max)()
2019 {
2020 initializer.do_nothing();
2021 static std::pair<bool, number_type> value;
2022 if(!value.first)
2023 {
2024 value.first = true;
2025 value.second = 0.5;
2026 mpfr_mul_2exp(value.second.backend().data(), value.second.backend().data(), mpfr_get_emax(), GMP_RNDN);
2027 }
2028 return value.second;
2029 }
2030 BOOST_STATIC_CONSTEXPR number_type lowest()
2031 {
2032 return -(max)();
2033 }
2034 BOOST_STATIC_CONSTEXPR int digits = static_cast<int>((Digits10 * 1000L) / 301L + ((Digits10 * 1000L) % 301 ? 2 : 1));
2035 BOOST_STATIC_CONSTEXPR int digits10 = Digits10;
2036 // Is this really correct???
2037 BOOST_STATIC_CONSTEXPR int max_digits10 = Digits10 + 3;
2038 BOOST_STATIC_CONSTEXPR bool is_signed = true;
2039 BOOST_STATIC_CONSTEXPR bool is_integer = false;
2040 BOOST_STATIC_CONSTEXPR bool is_exact = false;
2041 BOOST_STATIC_CONSTEXPR int radix = 2;
2042 static number_type epsilon()
2043 {
2044 initializer.do_nothing();
2045 static std::pair<bool, number_type> value;
2046 if(!value.first)
2047 {
2048 value.first = true;
2049 value.second = 1;
2050 mpfr_div_2exp(value.second.backend().data(), value.second.backend().data(), std::numeric_limits<number_type>::digits - 1, GMP_RNDN);
2051 }
2052 return value.second;
2053 }
2054 // What value should this be????
2055 static number_type round_error()
2056 {
2057 // returns epsilon/2
2058 initializer.do_nothing();
2059 static std::pair<bool, number_type> value;
2060 if(!value.first)
2061 {
2062 value.first = true;
2063 value.second = 1;
2064 mpfr_div_2exp(value.second.backend().data(), value.second.backend().data(), 1, GMP_RNDN);
2065 }
2066 return value.second;
2067 }
2068 BOOST_STATIC_CONSTEXPR long min_exponent = MPFR_EMIN_DEFAULT;
2069 BOOST_STATIC_CONSTEXPR long min_exponent10 = (MPFR_EMIN_DEFAULT / 1000) * 301L;
2070 BOOST_STATIC_CONSTEXPR long max_exponent = MPFR_EMAX_DEFAULT;
2071 BOOST_STATIC_CONSTEXPR long max_exponent10 = (MPFR_EMAX_DEFAULT / 1000) * 301L;
2072 BOOST_STATIC_CONSTEXPR bool has_infinity = true;
2073 BOOST_STATIC_CONSTEXPR bool has_quiet_NaN = true;
2074 BOOST_STATIC_CONSTEXPR bool has_signaling_NaN = false;
2075 BOOST_STATIC_CONSTEXPR float_denorm_style has_denorm = denorm_absent;
2076 BOOST_STATIC_CONSTEXPR bool has_denorm_loss = false;
2077 static number_type infinity()
2078 {
2079 // returns epsilon/2
2080 initializer.do_nothing();
2081 static std::pair<bool, number_type> value;
2082 if(!value.first)
2083 {
2084 value.first = true;
2085 value.second = 1;
2086 mpfr_set_inf(value.second.backend().data(), 1);
2087 }
2088 return value.second;
2089 }
2090 static number_type quiet_NaN()
2091 {
2092 // returns epsilon/2
2093 initializer.do_nothing();
2094 static std::pair<bool, number_type> value;
2095 if(!value.first)
2096 {
2097 value.first = true;
2098 value.second = 1;
2099 mpfr_set_nan(value.second.backend().data());
2100 }
2101 return value.second;
2102 }
2103 BOOST_STATIC_CONSTEXPR number_type signaling_NaN()
2104 {
2105 return number_type(0);
2106 }
2107 BOOST_STATIC_CONSTEXPR number_type denorm_min() { return number_type(0); }
2108 BOOST_STATIC_CONSTEXPR bool is_iec559 = false;
2109 BOOST_STATIC_CONSTEXPR bool is_bounded = true;
2110 BOOST_STATIC_CONSTEXPR bool is_modulo = false;
2111 BOOST_STATIC_CONSTEXPR bool traps = true;
2112 BOOST_STATIC_CONSTEXPR bool tinyness_before = false;
2113 BOOST_STATIC_CONSTEXPR float_round_style round_style = round_to_nearest;
2114
2115private:
2116 struct data_initializer
2117 {
2118 data_initializer()
2119 {
2120 std::numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<digits10, AllocateType> > >::epsilon();
2121 std::numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<digits10, AllocateType> > >::round_error();
2122 (std::numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<digits10, AllocateType> > >::min)();
2123 (std::numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<digits10, AllocateType> > >::max)();
2124 std::numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<digits10, AllocateType> > >::infinity();
2125 std::numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<digits10, AllocateType> > >::quiet_NaN();
2126 }
2127 void do_nothing()const{}
2128 };
2129 static const data_initializer initializer;
2130};
2131
2132template<unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2133const typename numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::data_initializer numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::initializer;
2134
2135#ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION
2136
2137template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2138BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::digits;
2139template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2140BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::digits10;
2141template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2142BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::max_digits10;
2143template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2144BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::is_signed;
2145template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2146BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::is_integer;
2147template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2148BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::is_exact;
2149template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2150BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::radix;
2151template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2152BOOST_CONSTEXPR_OR_CONST long numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::min_exponent;
2153template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2154BOOST_CONSTEXPR_OR_CONST long numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::min_exponent10;
2155template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2156BOOST_CONSTEXPR_OR_CONST long numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::max_exponent;
2157template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2158BOOST_CONSTEXPR_OR_CONST long numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::max_exponent10;
2159template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2160BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::has_infinity;
2161template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2162BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::has_quiet_NaN;
2163template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2164BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::has_signaling_NaN;
2165template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2166BOOST_CONSTEXPR_OR_CONST float_denorm_style numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::has_denorm;
2167template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2168BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::has_denorm_loss;
2169template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2170BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::is_iec559;
2171template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2172BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::is_bounded;
2173template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2174BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::is_modulo;
2175template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2176BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::traps;
2177template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2178BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::tinyness_before;
2179template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
2180BOOST_CONSTEXPR_OR_CONST float_round_style numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >::round_style;
2181
2182#endif
2183
2184
2185template<boost::multiprecision::expression_template_option ExpressionTemplates>
2186class numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >
2187{
2188 typedef boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> number_type;
2189public:
2190 BOOST_STATIC_CONSTEXPR bool is_specialized = false;
2191 static number_type (min)() { return number_type(0); }
2192 static number_type (max)() { return number_type(0); }
2193 static number_type lowest() { return number_type(0); }
2194 BOOST_STATIC_CONSTEXPR int digits = 0;
2195 BOOST_STATIC_CONSTEXPR int digits10 = 0;
2196 BOOST_STATIC_CONSTEXPR int max_digits10 = 0;
2197 BOOST_STATIC_CONSTEXPR bool is_signed = false;
2198 BOOST_STATIC_CONSTEXPR bool is_integer = false;
2199 BOOST_STATIC_CONSTEXPR bool is_exact = false;
2200 BOOST_STATIC_CONSTEXPR int radix = 0;
2201 static number_type epsilon() { return number_type(0); }
2202 static number_type round_error() { return number_type(0); }
2203 BOOST_STATIC_CONSTEXPR int min_exponent = 0;
2204 BOOST_STATIC_CONSTEXPR int min_exponent10 = 0;
2205 BOOST_STATIC_CONSTEXPR int max_exponent = 0;
2206 BOOST_STATIC_CONSTEXPR int max_exponent10 = 0;
2207 BOOST_STATIC_CONSTEXPR bool has_infinity = false;
2208 BOOST_STATIC_CONSTEXPR bool has_quiet_NaN = false;
2209 BOOST_STATIC_CONSTEXPR bool has_signaling_NaN = false;
2210 BOOST_STATIC_CONSTEXPR float_denorm_style has_denorm = denorm_absent;
2211 BOOST_STATIC_CONSTEXPR bool has_denorm_loss = false;
2212 static number_type infinity() { return number_type(0); }
2213 static number_type quiet_NaN() { return number_type(0); }
2214 static number_type signaling_NaN() { return number_type(0); }
2215 static number_type denorm_min() { return number_type(0); }
2216 BOOST_STATIC_CONSTEXPR bool is_iec559 = false;
2217 BOOST_STATIC_CONSTEXPR bool is_bounded = false;
2218 BOOST_STATIC_CONSTEXPR bool is_modulo = false;
2219 BOOST_STATIC_CONSTEXPR bool traps = false;
2220 BOOST_STATIC_CONSTEXPR bool tinyness_before = false;
2221 BOOST_STATIC_CONSTEXPR float_round_style round_style = round_toward_zero;
2222};
2223
2224#ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION
2225
2226template <boost::multiprecision::expression_template_option ExpressionTemplates>
2227BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::digits;
2228template <boost::multiprecision::expression_template_option ExpressionTemplates>
2229BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::digits10;
2230template <boost::multiprecision::expression_template_option ExpressionTemplates>
2231BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::max_digits10;
2232template <boost::multiprecision::expression_template_option ExpressionTemplates>
2233BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::is_signed;
2234template <boost::multiprecision::expression_template_option ExpressionTemplates>
2235BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::is_integer;
2236template <boost::multiprecision::expression_template_option ExpressionTemplates>
2237BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::is_exact;
2238template <boost::multiprecision::expression_template_option ExpressionTemplates>
2239BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::radix;
2240template <boost::multiprecision::expression_template_option ExpressionTemplates>
2241BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::min_exponent;
2242template <boost::multiprecision::expression_template_option ExpressionTemplates>
2243BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::min_exponent10;
2244template <boost::multiprecision::expression_template_option ExpressionTemplates>
2245BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::max_exponent;
2246template <boost::multiprecision::expression_template_option ExpressionTemplates>
2247BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::max_exponent10;
2248template <boost::multiprecision::expression_template_option ExpressionTemplates>
2249BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::has_infinity;
2250template <boost::multiprecision::expression_template_option ExpressionTemplates>
2251BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::has_quiet_NaN;
2252template <boost::multiprecision::expression_template_option ExpressionTemplates>
2253BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::has_signaling_NaN;
2254template <boost::multiprecision::expression_template_option ExpressionTemplates>
2255BOOST_CONSTEXPR_OR_CONST float_denorm_style numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::has_denorm;
2256template <boost::multiprecision::expression_template_option ExpressionTemplates>
2257BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::has_denorm_loss;
2258template <boost::multiprecision::expression_template_option ExpressionTemplates>
2259BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::is_iec559;
2260template <boost::multiprecision::expression_template_option ExpressionTemplates>
2261BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::is_bounded;
2262template <boost::multiprecision::expression_template_option ExpressionTemplates>
2263BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::is_modulo;
2264template <boost::multiprecision::expression_template_option ExpressionTemplates>
2265BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::traps;
2266template <boost::multiprecision::expression_template_option ExpressionTemplates>
2267BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::tinyness_before;
2268template <boost::multiprecision::expression_template_option ExpressionTemplates>
2269BOOST_CONSTEXPR_OR_CONST float_round_style numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<0>, ExpressionTemplates> >::round_style;
2270
2271#endif
2272} // namespace std
2273#endif