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