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