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