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