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