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_ER_GMP_BACKEND_HPP
|
Chris@16
|
7 #define BOOST_MATH_ER_GMP_BACKEND_HPP
|
Chris@16
|
8
|
Chris@16
|
9 #include <boost/multiprecision/number.hpp>
|
Chris@16
|
10 #include <boost/multiprecision/detail/integer_ops.hpp>
|
Chris@16
|
11 #include <boost/multiprecision/detail/big_lanczos.hpp>
|
Chris@16
|
12 #include <boost/multiprecision/detail/digits.hpp>
|
Chris@16
|
13 #include <boost/math/special_functions/fpclassify.hpp>
|
Chris@16
|
14 #include <boost/cstdint.hpp>
|
Chris@16
|
15 #ifdef BOOST_MSVC
|
Chris@16
|
16 # pragma warning(push)
|
Chris@16
|
17 # pragma warning(disable:4127)
|
Chris@16
|
18 #endif
|
Chris@16
|
19 #include <gmp.h>
|
Chris@16
|
20 #ifdef BOOST_MSVC
|
Chris@16
|
21 # pragma warning(pop)
|
Chris@16
|
22 #endif
|
Chris@16
|
23 #include <cmath>
|
Chris@16
|
24 #include <limits>
|
Chris@16
|
25 #include <climits>
|
Chris@16
|
26
|
Chris@16
|
27 namespace boost{
|
Chris@16
|
28 namespace multiprecision{
|
Chris@16
|
29 namespace backends{
|
Chris@16
|
30
|
Chris@16
|
31 #ifdef BOOST_MSVC
|
Chris@16
|
32 // warning C4127: conditional expression is constant
|
Chris@16
|
33 #pragma warning(push)
|
Chris@16
|
34 #pragma warning(disable:4127)
|
Chris@16
|
35 #endif
|
Chris@16
|
36
|
Chris@16
|
37 template <unsigned digits10>
|
Chris@16
|
38 struct gmp_float;
|
Chris@16
|
39 struct gmp_int;
|
Chris@16
|
40 struct gmp_rational;
|
Chris@16
|
41
|
Chris@16
|
42 } // namespace backends
|
Chris@16
|
43
|
Chris@16
|
44 template<>
|
Chris@16
|
45 struct number_category<backends::gmp_int> : public mpl::int_<number_kind_integer>{};
|
Chris@16
|
46 template<>
|
Chris@16
|
47 struct number_category<backends::gmp_rational> : public mpl::int_<number_kind_rational>{};
|
Chris@16
|
48 template <unsigned digits10>
|
Chris@16
|
49 struct number_category<backends::gmp_float<digits10> > : public mpl::int_<number_kind_floating_point>{};
|
Chris@16
|
50
|
Chris@16
|
51 namespace backends{
|
Chris@16
|
52 //
|
Chris@16
|
53 // Within this file, the only functions we mark as noexcept are those that manipulate
|
Chris@16
|
54 // (but don't create) an mpf_t. All other types may allocate at pretty much any time
|
Chris@16
|
55 // via a user-supplied allocator, and therefore throw.
|
Chris@16
|
56 //
|
Chris@16
|
57 namespace detail{
|
Chris@16
|
58
|
Chris@16
|
59 template <unsigned digits10>
|
Chris@16
|
60 struct gmp_float_imp
|
Chris@16
|
61 {
|
Chris@16
|
62 typedef mpl::list<long, long long> signed_types;
|
Chris@16
|
63 typedef mpl::list<unsigned long, unsigned long long> unsigned_types;
|
Chris@16
|
64 typedef mpl::list<double, long double> float_types;
|
Chris@16
|
65 typedef long exponent_type;
|
Chris@16
|
66
|
Chris@16
|
67 gmp_float_imp() BOOST_NOEXCEPT {}
|
Chris@16
|
68
|
Chris@16
|
69 gmp_float_imp(const gmp_float_imp& o)
|
Chris@16
|
70 {
|
Chris@16
|
71 //
|
Chris@16
|
72 // We have to do an init followed by a set here, otherwise *this may be at
|
Chris@16
|
73 // a lower precision than o: seems like mpf_init_set copies just enough bits
|
Chris@16
|
74 // to get the right value, but if it's then used in further calculations
|
Chris@16
|
75 // things go badly wrong!!
|
Chris@16
|
76 //
|
Chris@16
|
77 mpf_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision()));
|
Chris@16
|
78 if(o.m_data[0]._mp_d)
|
Chris@16
|
79 mpf_set(m_data, o.m_data);
|
Chris@16
|
80 }
|
Chris@16
|
81 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
|
Chris@16
|
82 gmp_float_imp(gmp_float_imp&& o) BOOST_NOEXCEPT
|
Chris@16
|
83 {
|
Chris@16
|
84 m_data[0] = o.m_data[0];
|
Chris@16
|
85 o.m_data[0]._mp_d = 0;
|
Chris@16
|
86 }
|
Chris@16
|
87 #endif
|
Chris@16
|
88 gmp_float_imp& operator = (const gmp_float_imp& o)
|
Chris@16
|
89 {
|
Chris@16
|
90 if(m_data[0]._mp_d == 0)
|
Chris@16
|
91 mpf_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision()));
|
Chris@16
|
92 if(o.m_data[0]._mp_d)
|
Chris@16
|
93 mpf_set(m_data, o.m_data);
|
Chris@16
|
94 return *this;
|
Chris@16
|
95 }
|
Chris@16
|
96 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
|
Chris@16
|
97 gmp_float_imp& operator = (gmp_float_imp&& o) BOOST_NOEXCEPT
|
Chris@16
|
98 {
|
Chris@16
|
99 mpf_swap(m_data, o.m_data);
|
Chris@16
|
100 return *this;
|
Chris@16
|
101 }
|
Chris@16
|
102 #endif
|
Chris@16
|
103 gmp_float_imp& operator = (unsigned long long i)
|
Chris@16
|
104 {
|
Chris@16
|
105 if(m_data[0]._mp_d == 0)
|
Chris@16
|
106 mpf_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision()));
|
Chris@16
|
107 unsigned long long mask = ((1uLL << std::numeric_limits<unsigned>::digits) - 1);
|
Chris@16
|
108 unsigned shift = 0;
|
Chris@16
|
109 mpf_t t;
|
Chris@16
|
110 mpf_init2(t, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision()));
|
Chris@16
|
111 mpf_set_ui(m_data, 0);
|
Chris@16
|
112 while(i)
|
Chris@16
|
113 {
|
Chris@16
|
114 mpf_set_ui(t, static_cast<unsigned>(i & mask));
|
Chris@16
|
115 if(shift)
|
Chris@16
|
116 mpf_mul_2exp(t, t, shift);
|
Chris@16
|
117 mpf_add(m_data, m_data, t);
|
Chris@16
|
118 shift += std::numeric_limits<unsigned>::digits;
|
Chris@16
|
119 i >>= std::numeric_limits<unsigned>::digits;
|
Chris@16
|
120 }
|
Chris@16
|
121 mpf_clear(t);
|
Chris@16
|
122 return *this;
|
Chris@16
|
123 }
|
Chris@16
|
124 gmp_float_imp& operator = (long long i)
|
Chris@16
|
125 {
|
Chris@16
|
126 if(m_data[0]._mp_d == 0)
|
Chris@16
|
127 mpf_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision()));
|
Chris@16
|
128 bool neg = i < 0;
|
Chris@101
|
129 *this = static_cast<unsigned long long>(boost::multiprecision::detail::unsigned_abs(i));
|
Chris@16
|
130 if(neg)
|
Chris@16
|
131 mpf_neg(m_data, m_data);
|
Chris@16
|
132 return *this;
|
Chris@16
|
133 }
|
Chris@16
|
134 gmp_float_imp& operator = (unsigned long i)
|
Chris@16
|
135 {
|
Chris@16
|
136 if(m_data[0]._mp_d == 0)
|
Chris@16
|
137 mpf_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision()));
|
Chris@16
|
138 mpf_set_ui(m_data, i);
|
Chris@16
|
139 return *this;
|
Chris@16
|
140 }
|
Chris@16
|
141 gmp_float_imp& operator = (long i)
|
Chris@16
|
142 {
|
Chris@16
|
143 if(m_data[0]._mp_d == 0)
|
Chris@16
|
144 mpf_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision()));
|
Chris@16
|
145 mpf_set_si(m_data, i);
|
Chris@16
|
146 return *this;
|
Chris@16
|
147 }
|
Chris@16
|
148 gmp_float_imp& operator = (double d)
|
Chris@16
|
149 {
|
Chris@16
|
150 if(m_data[0]._mp_d == 0)
|
Chris@16
|
151 mpf_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision()));
|
Chris@16
|
152 mpf_set_d(m_data, d);
|
Chris@16
|
153 return *this;
|
Chris@16
|
154 }
|
Chris@16
|
155 gmp_float_imp& operator = (long double a)
|
Chris@16
|
156 {
|
Chris@16
|
157 using std::frexp;
|
Chris@16
|
158 using std::ldexp;
|
Chris@16
|
159 using std::floor;
|
Chris@16
|
160
|
Chris@16
|
161 if(m_data[0]._mp_d == 0)
|
Chris@16
|
162 mpf_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision()));
|
Chris@16
|
163
|
Chris@16
|
164 if (a == 0) {
|
Chris@16
|
165 mpf_set_si(m_data, 0);
|
Chris@16
|
166 return *this;
|
Chris@16
|
167 }
|
Chris@16
|
168
|
Chris@16
|
169 if (a == 1) {
|
Chris@16
|
170 mpf_set_si(m_data, 1);
|
Chris@16
|
171 return *this;
|
Chris@16
|
172 }
|
Chris@16
|
173
|
Chris@16
|
174 BOOST_ASSERT(!(boost::math::isinf)(a));
|
Chris@16
|
175 BOOST_ASSERT(!(boost::math::isnan)(a));
|
Chris@16
|
176
|
Chris@16
|
177 int e;
|
Chris@16
|
178 long double f, term;
|
Chris@16
|
179 mpf_set_ui(m_data, 0u);
|
Chris@16
|
180
|
Chris@16
|
181 f = frexp(a, &e);
|
Chris@16
|
182
|
Chris@16
|
183 static const int shift = std::numeric_limits<int>::digits - 1;
|
Chris@16
|
184
|
Chris@16
|
185 while(f)
|
Chris@16
|
186 {
|
Chris@16
|
187 // extract int sized bits from f:
|
Chris@16
|
188 f = ldexp(f, shift);
|
Chris@16
|
189 term = floor(f);
|
Chris@16
|
190 e -= shift;
|
Chris@16
|
191 mpf_mul_2exp(m_data, m_data, shift);
|
Chris@16
|
192 if(term > 0)
|
Chris@16
|
193 mpf_add_ui(m_data, m_data, static_cast<unsigned>(term));
|
Chris@16
|
194 else
|
Chris@16
|
195 mpf_sub_ui(m_data, m_data, static_cast<unsigned>(-term));
|
Chris@16
|
196 f -= term;
|
Chris@16
|
197 }
|
Chris@16
|
198 if(e > 0)
|
Chris@16
|
199 mpf_mul_2exp(m_data, m_data, e);
|
Chris@16
|
200 else if(e < 0)
|
Chris@16
|
201 mpf_div_2exp(m_data, m_data, -e);
|
Chris@16
|
202 return *this;
|
Chris@16
|
203 }
|
Chris@16
|
204 gmp_float_imp& operator = (const char* s)
|
Chris@16
|
205 {
|
Chris@16
|
206 if(m_data[0]._mp_d == 0)
|
Chris@16
|
207 mpf_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision()));
|
Chris@16
|
208 if(0 != mpf_set_str(m_data, s, 10))
|
Chris@16
|
209 BOOST_THROW_EXCEPTION(std::runtime_error(std::string("The string \"") + s + std::string("\"could not be interpreted as a valid floating point number.")));
|
Chris@16
|
210 return *this;
|
Chris@16
|
211 }
|
Chris@16
|
212 void swap(gmp_float_imp& o) BOOST_NOEXCEPT
|
Chris@16
|
213 {
|
Chris@16
|
214 mpf_swap(m_data, o.m_data);
|
Chris@16
|
215 }
|
Chris@16
|
216 std::string str(std::streamsize digits, std::ios_base::fmtflags f)const
|
Chris@16
|
217 {
|
Chris@16
|
218 BOOST_ASSERT(m_data[0]._mp_d);
|
Chris@16
|
219
|
Chris@16
|
220 bool scientific = (f & std::ios_base::scientific) == std::ios_base::scientific;
|
Chris@16
|
221 bool fixed = (f & std::ios_base::fixed) == std::ios_base::fixed;
|
Chris@16
|
222 std::streamsize org_digits(digits);
|
Chris@16
|
223
|
Chris@16
|
224 if(scientific && digits)
|
Chris@16
|
225 ++digits;
|
Chris@16
|
226
|
Chris@16
|
227 std::string result;
|
Chris@16
|
228 mp_exp_t e;
|
Chris@16
|
229 void *(*alloc_func_ptr) (size_t);
|
Chris@16
|
230 void *(*realloc_func_ptr) (void *, size_t, size_t);
|
Chris@16
|
231 void (*free_func_ptr) (void *, size_t);
|
Chris@16
|
232 mp_get_memory_functions(&alloc_func_ptr, &realloc_func_ptr, &free_func_ptr);
|
Chris@16
|
233
|
Chris@16
|
234 if(mpf_sgn(m_data) == 0)
|
Chris@16
|
235 {
|
Chris@16
|
236 e = 0;
|
Chris@16
|
237 result = "0";
|
Chris@16
|
238 if(fixed && digits)
|
Chris@16
|
239 ++digits;
|
Chris@16
|
240 }
|
Chris@16
|
241 else
|
Chris@16
|
242 {
|
Chris@16
|
243 char* ps = mpf_get_str (0, &e, 10, static_cast<std::size_t>(digits), m_data);
|
Chris@16
|
244 --e; // To match with what our formatter expects.
|
Chris@16
|
245 if(fixed && e != -1)
|
Chris@16
|
246 {
|
Chris@16
|
247 // Oops we actually need a different number of digits to what we asked for:
|
Chris@16
|
248 (*free_func_ptr)((void*)ps, std::strlen(ps) + 1);
|
Chris@16
|
249 digits += e + 1;
|
Chris@16
|
250 if(digits == 0)
|
Chris@16
|
251 {
|
Chris@16
|
252 // We need to get *all* the digits and then possibly round up,
|
Chris@16
|
253 // we end up with either "0" or "1" as the result.
|
Chris@16
|
254 ps = mpf_get_str (0, &e, 10, 0, m_data);
|
Chris@16
|
255 --e;
|
Chris@16
|
256 unsigned offset = *ps == '-' ? 1 : 0;
|
Chris@16
|
257 if(ps[offset] > '5')
|
Chris@16
|
258 {
|
Chris@16
|
259 ++e;
|
Chris@16
|
260 ps[offset] = '1';
|
Chris@16
|
261 ps[offset + 1] = 0;
|
Chris@16
|
262 }
|
Chris@16
|
263 else if(ps[offset] == '5')
|
Chris@16
|
264 {
|
Chris@16
|
265 unsigned i = offset + 1;
|
Chris@16
|
266 bool round_up = false;
|
Chris@16
|
267 while(ps[i] != 0)
|
Chris@16
|
268 {
|
Chris@16
|
269 if(ps[i] != '0')
|
Chris@16
|
270 {
|
Chris@16
|
271 round_up = true;
|
Chris@16
|
272 break;
|
Chris@16
|
273 }
|
Chris@16
|
274 }
|
Chris@16
|
275 if(round_up)
|
Chris@16
|
276 {
|
Chris@16
|
277 ++e;
|
Chris@16
|
278 ps[offset] = '1';
|
Chris@16
|
279 ps[offset + 1] = 0;
|
Chris@16
|
280 }
|
Chris@16
|
281 else
|
Chris@16
|
282 {
|
Chris@16
|
283 ps[offset] = '0';
|
Chris@16
|
284 ps[offset + 1] = 0;
|
Chris@16
|
285 }
|
Chris@16
|
286 }
|
Chris@16
|
287 else
|
Chris@16
|
288 {
|
Chris@16
|
289 ps[offset] = '0';
|
Chris@16
|
290 ps[offset + 1] = 0;
|
Chris@16
|
291 }
|
Chris@16
|
292 }
|
Chris@16
|
293 else if(digits > 0)
|
Chris@16
|
294 {
|
Chris@16
|
295 ps = mpf_get_str (0, &e, 10, static_cast<std::size_t>(digits), m_data);
|
Chris@16
|
296 --e; // To match with what our formatter expects.
|
Chris@16
|
297 }
|
Chris@16
|
298 else
|
Chris@16
|
299 {
|
Chris@16
|
300 ps = mpf_get_str (0, &e, 10, 1, m_data);
|
Chris@16
|
301 --e;
|
Chris@16
|
302 unsigned offset = *ps == '-' ? 1 : 0;
|
Chris@16
|
303 ps[offset] = '0';
|
Chris@16
|
304 ps[offset + 1] = 0;
|
Chris@16
|
305 }
|
Chris@16
|
306 }
|
Chris@16
|
307 result = ps;
|
Chris@16
|
308 (*free_func_ptr)((void*)ps, std::strlen(ps) + 1);
|
Chris@16
|
309 }
|
Chris@16
|
310 boost::multiprecision::detail::format_float_string(result, e, org_digits, f, mpf_sgn(m_data) == 0);
|
Chris@16
|
311 return result;
|
Chris@16
|
312 }
|
Chris@16
|
313 ~gmp_float_imp() BOOST_NOEXCEPT
|
Chris@16
|
314 {
|
Chris@16
|
315 if(m_data[0]._mp_d)
|
Chris@16
|
316 mpf_clear(m_data);
|
Chris@16
|
317 }
|
Chris@16
|
318 void negate() BOOST_NOEXCEPT
|
Chris@16
|
319 {
|
Chris@16
|
320 BOOST_ASSERT(m_data[0]._mp_d);
|
Chris@16
|
321 mpf_neg(m_data, m_data);
|
Chris@16
|
322 }
|
Chris@16
|
323 int compare(const gmp_float<digits10>& o)const BOOST_NOEXCEPT
|
Chris@16
|
324 {
|
Chris@16
|
325 BOOST_ASSERT(m_data[0]._mp_d && o.m_data[0]._mp_d);
|
Chris@16
|
326 return mpf_cmp(m_data, o.m_data);
|
Chris@16
|
327 }
|
Chris@16
|
328 int compare(long i)const BOOST_NOEXCEPT
|
Chris@16
|
329 {
|
Chris@16
|
330 BOOST_ASSERT(m_data[0]._mp_d);
|
Chris@16
|
331 return mpf_cmp_si(m_data, i);
|
Chris@16
|
332 }
|
Chris@16
|
333 int compare(unsigned long i)const BOOST_NOEXCEPT
|
Chris@16
|
334 {
|
Chris@16
|
335 BOOST_ASSERT(m_data[0]._mp_d);
|
Chris@16
|
336 return mpf_cmp_ui(m_data, i);
|
Chris@16
|
337 }
|
Chris@16
|
338 template <class V>
|
Chris@16
|
339 typename enable_if<is_arithmetic<V>, int>::type compare(V v)const
|
Chris@16
|
340 {
|
Chris@16
|
341 gmp_float<digits10> d;
|
Chris@16
|
342 d = v;
|
Chris@16
|
343 return compare(d);
|
Chris@16
|
344 }
|
Chris@16
|
345 mpf_t& data() BOOST_NOEXCEPT
|
Chris@16
|
346 {
|
Chris@16
|
347 BOOST_ASSERT(m_data[0]._mp_d);
|
Chris@16
|
348 return m_data;
|
Chris@16
|
349 }
|
Chris@16
|
350 const mpf_t& data()const BOOST_NOEXCEPT
|
Chris@16
|
351 {
|
Chris@16
|
352 BOOST_ASSERT(m_data[0]._mp_d);
|
Chris@16
|
353 return m_data;
|
Chris@16
|
354 }
|
Chris@16
|
355 protected:
|
Chris@16
|
356 mpf_t m_data;
|
Chris@16
|
357 static unsigned& get_default_precision() BOOST_NOEXCEPT
|
Chris@16
|
358 {
|
Chris@16
|
359 static unsigned val = 50;
|
Chris@16
|
360 return val;
|
Chris@16
|
361 }
|
Chris@16
|
362 };
|
Chris@16
|
363
|
Chris@16
|
364 } // namespace detail
|
Chris@16
|
365
|
Chris@16
|
366 struct gmp_int;
|
Chris@16
|
367 struct gmp_rational;
|
Chris@16
|
368
|
Chris@16
|
369 template <unsigned digits10>
|
Chris@16
|
370 struct gmp_float : public detail::gmp_float_imp<digits10>
|
Chris@16
|
371 {
|
Chris@16
|
372 gmp_float()
|
Chris@16
|
373 {
|
Chris@16
|
374 mpf_init2(this->m_data, multiprecision::detail::digits10_2_2(digits10));
|
Chris@16
|
375 }
|
Chris@16
|
376 gmp_float(const gmp_float& o) : detail::gmp_float_imp<digits10>(o) {}
|
Chris@16
|
377 template <unsigned D>
|
Chris@16
|
378 gmp_float(const gmp_float<D>& o, typename enable_if_c<D <= digits10>::type* = 0);
|
Chris@16
|
379 template <unsigned D>
|
Chris@16
|
380 explicit gmp_float(const gmp_float<D>& o, typename disable_if_c<D <= digits10>::type* = 0);
|
Chris@16
|
381 gmp_float(const gmp_int& o);
|
Chris@16
|
382 gmp_float(const gmp_rational& o);
|
Chris@16
|
383 gmp_float(const mpf_t val)
|
Chris@16
|
384 {
|
Chris@16
|
385 mpf_init2(this->m_data, multiprecision::detail::digits10_2_2(digits10));
|
Chris@16
|
386 mpf_set(this->m_data, val);
|
Chris@16
|
387 }
|
Chris@16
|
388 gmp_float(const mpz_t val)
|
Chris@16
|
389 {
|
Chris@16
|
390 mpf_init2(this->m_data, multiprecision::detail::digits10_2_2(digits10));
|
Chris@16
|
391 mpf_set_z(this->m_data, val);
|
Chris@16
|
392 }
|
Chris@16
|
393 gmp_float(const mpq_t val)
|
Chris@16
|
394 {
|
Chris@16
|
395 mpf_init2(this->m_data, multiprecision::detail::digits10_2_2(digits10));
|
Chris@16
|
396 mpf_set_q(this->m_data, val);
|
Chris@16
|
397 }
|
Chris@16
|
398 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
|
Chris@16
|
399 gmp_float(gmp_float&& o) BOOST_NOEXCEPT : detail::gmp_float_imp<digits10>(static_cast<detail::gmp_float_imp<digits10>&&>(o)) {}
|
Chris@16
|
400 #endif
|
Chris@16
|
401 gmp_float& operator=(const gmp_float& o)
|
Chris@16
|
402 {
|
Chris@16
|
403 *static_cast<detail::gmp_float_imp<digits10>*>(this) = static_cast<detail::gmp_float_imp<digits10> const&>(o);
|
Chris@16
|
404 return *this;
|
Chris@16
|
405 }
|
Chris@16
|
406 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
|
Chris@16
|
407 gmp_float& operator=(gmp_float&& o) BOOST_NOEXCEPT
|
Chris@16
|
408 {
|
Chris@16
|
409 *static_cast<detail::gmp_float_imp<digits10>*>(this) = static_cast<detail::gmp_float_imp<digits10>&&>(o);
|
Chris@16
|
410 return *this;
|
Chris@16
|
411 }
|
Chris@16
|
412 #endif
|
Chris@16
|
413 template <unsigned D>
|
Chris@16
|
414 gmp_float& operator=(const gmp_float<D>& o);
|
Chris@16
|
415 gmp_float& operator=(const gmp_int& o);
|
Chris@16
|
416 gmp_float& operator=(const gmp_rational& o);
|
Chris@16
|
417 gmp_float& operator=(const mpf_t val)
|
Chris@16
|
418 {
|
Chris@16
|
419 if(this->m_data[0]._mp_d == 0)
|
Chris@16
|
420 mpf_init2(this->m_data, multiprecision::detail::digits10_2_2(digits10));
|
Chris@16
|
421 mpf_set(this->m_data, val);
|
Chris@16
|
422 return *this;
|
Chris@16
|
423 }
|
Chris@16
|
424 gmp_float& operator=(const mpz_t val)
|
Chris@16
|
425 {
|
Chris@16
|
426 if(this->m_data[0]._mp_d == 0)
|
Chris@16
|
427 mpf_init2(this->m_data, multiprecision::detail::digits10_2_2(digits10));
|
Chris@16
|
428 mpf_set_z(this->m_data, val);
|
Chris@16
|
429 return *this;
|
Chris@16
|
430 }
|
Chris@16
|
431 gmp_float& operator=(const mpq_t val)
|
Chris@16
|
432 {
|
Chris@16
|
433 if(this->m_data[0]._mp_d == 0)
|
Chris@16
|
434 mpf_init2(this->m_data, multiprecision::detail::digits10_2_2(digits10));
|
Chris@16
|
435 mpf_set_q(this->m_data, val);
|
Chris@16
|
436 return *this;
|
Chris@16
|
437 }
|
Chris@16
|
438 template <class V>
|
Chris@16
|
439 gmp_float& operator=(const V& v)
|
Chris@16
|
440 {
|
Chris@16
|
441 *static_cast<detail::gmp_float_imp<digits10>*>(this) = v;
|
Chris@16
|
442 return *this;
|
Chris@16
|
443 }
|
Chris@16
|
444 };
|
Chris@16
|
445
|
Chris@16
|
446 template <>
|
Chris@16
|
447 struct gmp_float<0> : public detail::gmp_float_imp<0>
|
Chris@16
|
448 {
|
Chris@16
|
449 gmp_float()
|
Chris@16
|
450 {
|
Chris@16
|
451 mpf_init2(this->m_data, multiprecision::detail::digits10_2_2(get_default_precision()));
|
Chris@16
|
452 }
|
Chris@16
|
453 gmp_float(const mpf_t val)
|
Chris@16
|
454 {
|
Chris@16
|
455 mpf_init2(this->m_data, multiprecision::detail::digits10_2_2(get_default_precision()));
|
Chris@16
|
456 mpf_set(this->m_data, val);
|
Chris@16
|
457 }
|
Chris@16
|
458 gmp_float(const mpz_t val)
|
Chris@16
|
459 {
|
Chris@16
|
460 mpf_init2(this->m_data, multiprecision::detail::digits10_2_2(get_default_precision()));
|
Chris@16
|
461 mpf_set_z(this->m_data, val);
|
Chris@16
|
462 }
|
Chris@16
|
463 gmp_float(const mpq_t val)
|
Chris@16
|
464 {
|
Chris@16
|
465 mpf_init2(this->m_data, multiprecision::detail::digits10_2_2(get_default_precision()));
|
Chris@16
|
466 mpf_set_q(this->m_data, val);
|
Chris@16
|
467 }
|
Chris@16
|
468 gmp_float(const gmp_float& o) : detail::gmp_float_imp<0>(o) {}
|
Chris@16
|
469 template <unsigned D>
|
Chris@16
|
470 gmp_float(const gmp_float<D>& o)
|
Chris@16
|
471 {
|
Chris@16
|
472 mpf_init2(this->m_data, mpf_get_prec(o.data()));
|
Chris@16
|
473 mpf_set(this->m_data, o.data());
|
Chris@16
|
474 }
|
Chris@16
|
475 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
|
Chris@16
|
476 gmp_float(gmp_float&& o) BOOST_NOEXCEPT : detail::gmp_float_imp<0>(static_cast<detail::gmp_float_imp<0>&&>(o)) {}
|
Chris@16
|
477 #endif
|
Chris@16
|
478 gmp_float(const gmp_int& o);
|
Chris@16
|
479 gmp_float(const gmp_rational& o);
|
Chris@16
|
480 gmp_float(const gmp_float& o, unsigned digits10)
|
Chris@16
|
481 {
|
Chris@16
|
482 mpf_init2(this->m_data, multiprecision::detail::digits10_2_2(digits10));
|
Chris@16
|
483 mpf_set(this->m_data, o.data());
|
Chris@16
|
484 }
|
Chris@16
|
485
|
Chris@16
|
486 gmp_float& operator=(const gmp_float& o)
|
Chris@16
|
487 {
|
Chris@16
|
488 *static_cast<detail::gmp_float_imp<0>*>(this) = static_cast<detail::gmp_float_imp<0> const&>(o);
|
Chris@16
|
489 return *this;
|
Chris@16
|
490 }
|
Chris@16
|
491 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
|
Chris@16
|
492 gmp_float& operator=(gmp_float&& o) BOOST_NOEXCEPT
|
Chris@16
|
493 {
|
Chris@16
|
494 *static_cast<detail::gmp_float_imp<0>*>(this) = static_cast<detail::gmp_float_imp<0> &&>(o);
|
Chris@16
|
495 return *this;
|
Chris@16
|
496 }
|
Chris@16
|
497 #endif
|
Chris@16
|
498 template <unsigned D>
|
Chris@16
|
499 gmp_float& operator=(const gmp_float<D>& o)
|
Chris@16
|
500 {
|
Chris@16
|
501 if(this->m_data[0]._mp_d == 0)
|
Chris@16
|
502 {
|
Chris@16
|
503 mpf_init2(this->m_data, mpf_get_prec(o.data()));
|
Chris@16
|
504 }
|
Chris@16
|
505 else
|
Chris@16
|
506 {
|
Chris@16
|
507 mpf_set_prec(this->m_data, mpf_get_prec(o.data()));
|
Chris@16
|
508 }
|
Chris@16
|
509 mpf_set(this->m_data, o.data());
|
Chris@16
|
510 return *this;
|
Chris@16
|
511 }
|
Chris@16
|
512 gmp_float& operator=(const gmp_int& o);
|
Chris@16
|
513 gmp_float& operator=(const gmp_rational& o);
|
Chris@16
|
514 gmp_float& operator=(const mpf_t val)
|
Chris@16
|
515 {
|
Chris@16
|
516 if(this->m_data[0]._mp_d == 0)
|
Chris@16
|
517 mpf_init2(this->m_data, multiprecision::detail::digits10_2_2(get_default_precision()));
|
Chris@16
|
518 mpf_set(this->m_data, val);
|
Chris@16
|
519 return *this;
|
Chris@16
|
520 }
|
Chris@16
|
521 gmp_float& operator=(const mpz_t val)
|
Chris@16
|
522 {
|
Chris@16
|
523 if(this->m_data[0]._mp_d == 0)
|
Chris@16
|
524 mpf_init2(this->m_data, multiprecision::detail::digits10_2_2(get_default_precision()));
|
Chris@16
|
525 mpf_set_z(this->m_data, val);
|
Chris@16
|
526 return *this;
|
Chris@16
|
527 }
|
Chris@16
|
528 gmp_float& operator=(const mpq_t val)
|
Chris@16
|
529 {
|
Chris@16
|
530 if(this->m_data[0]._mp_d == 0)
|
Chris@16
|
531 mpf_init2(this->m_data, multiprecision::detail::digits10_2_2(get_default_precision()));
|
Chris@16
|
532 mpf_set_q(this->m_data, val);
|
Chris@16
|
533 return *this;
|
Chris@16
|
534 }
|
Chris@16
|
535 template <class V>
|
Chris@16
|
536 gmp_float& operator=(const V& v)
|
Chris@16
|
537 {
|
Chris@16
|
538 *static_cast<detail::gmp_float_imp<0>*>(this) = v;
|
Chris@16
|
539 return *this;
|
Chris@16
|
540 }
|
Chris@16
|
541 static unsigned default_precision() BOOST_NOEXCEPT
|
Chris@16
|
542 {
|
Chris@16
|
543 return get_default_precision();
|
Chris@16
|
544 }
|
Chris@16
|
545 static void default_precision(unsigned v) BOOST_NOEXCEPT
|
Chris@16
|
546 {
|
Chris@16
|
547 get_default_precision() = v;
|
Chris@16
|
548 }
|
Chris@16
|
549 unsigned precision()const BOOST_NOEXCEPT
|
Chris@16
|
550 {
|
Chris@16
|
551 return multiprecision::detail::digits2_2_10(mpf_get_prec(this->m_data));
|
Chris@16
|
552 }
|
Chris@16
|
553 void precision(unsigned digits10) BOOST_NOEXCEPT
|
Chris@16
|
554 {
|
Chris@16
|
555 mpf_set_prec(this->m_data, multiprecision::detail::digits10_2_2(digits10));
|
Chris@16
|
556 }
|
Chris@16
|
557 };
|
Chris@16
|
558
|
Chris@16
|
559 template <unsigned digits10, class T>
|
Chris@16
|
560 inline typename enable_if_c<is_arithmetic<T>::value, bool>::type eval_eq(const gmp_float<digits10>& a, const T& b) BOOST_NOEXCEPT
|
Chris@16
|
561 {
|
Chris@16
|
562 return a.compare(b) == 0;
|
Chris@16
|
563 }
|
Chris@16
|
564 template <unsigned digits10, class T>
|
Chris@16
|
565 inline typename enable_if_c<is_arithmetic<T>::value, bool>::type eval_lt(const gmp_float<digits10>& a, const T& b) BOOST_NOEXCEPT
|
Chris@16
|
566 {
|
Chris@16
|
567 return a.compare(b) < 0;
|
Chris@16
|
568 }
|
Chris@16
|
569 template <unsigned digits10, class T>
|
Chris@16
|
570 inline typename enable_if_c<is_arithmetic<T>::value, bool>::type eval_gt(const gmp_float<digits10>& a, const T& b) BOOST_NOEXCEPT
|
Chris@16
|
571 {
|
Chris@16
|
572 return a.compare(b) > 0;
|
Chris@16
|
573 }
|
Chris@16
|
574
|
Chris@16
|
575 template <unsigned D1, unsigned D2>
|
Chris@16
|
576 inline void eval_add(gmp_float<D1>& result, const gmp_float<D2>& o)
|
Chris@16
|
577 {
|
Chris@16
|
578 mpf_add(result.data(), result.data(), o.data());
|
Chris@16
|
579 }
|
Chris@16
|
580 template <unsigned D1, unsigned D2>
|
Chris@16
|
581 inline void eval_subtract(gmp_float<D1>& result, const gmp_float<D2>& o)
|
Chris@16
|
582 {
|
Chris@16
|
583 mpf_sub(result.data(), result.data(), o.data());
|
Chris@16
|
584 }
|
Chris@16
|
585 template <unsigned D1, unsigned D2>
|
Chris@16
|
586 inline void eval_multiply(gmp_float<D1>& result, const gmp_float<D2>& o)
|
Chris@16
|
587 {
|
Chris@16
|
588 mpf_mul(result.data(), result.data(), o.data());
|
Chris@16
|
589 }
|
Chris@16
|
590 template <unsigned digits10>
|
Chris@16
|
591 inline bool eval_is_zero(const gmp_float<digits10>& val) BOOST_NOEXCEPT
|
Chris@16
|
592 {
|
Chris@16
|
593 return mpf_sgn(val.data()) == 0;
|
Chris@16
|
594 }
|
Chris@16
|
595 template <unsigned D1, unsigned D2>
|
Chris@16
|
596 inline void eval_divide(gmp_float<D1>& result, const gmp_float<D2>& o)
|
Chris@16
|
597 {
|
Chris@16
|
598 if(eval_is_zero(o))
|
Chris@16
|
599 BOOST_THROW_EXCEPTION(std::overflow_error("Division by zero."));
|
Chris@16
|
600 mpf_div(result.data(), result.data(), o.data());
|
Chris@16
|
601 }
|
Chris@16
|
602 template <unsigned digits10>
|
Chris@16
|
603 inline void eval_add(gmp_float<digits10>& result, unsigned long i)
|
Chris@16
|
604 {
|
Chris@16
|
605 mpf_add_ui(result.data(), result.data(), i);
|
Chris@16
|
606 }
|
Chris@16
|
607 template <unsigned digits10>
|
Chris@16
|
608 inline void eval_subtract(gmp_float<digits10>& result, unsigned long i)
|
Chris@16
|
609 {
|
Chris@16
|
610 mpf_sub_ui(result.data(), result.data(), i);
|
Chris@16
|
611 }
|
Chris@16
|
612 template <unsigned digits10>
|
Chris@16
|
613 inline void eval_multiply(gmp_float<digits10>& result, unsigned long i)
|
Chris@16
|
614 {
|
Chris@16
|
615 mpf_mul_ui(result.data(), result.data(), i);
|
Chris@16
|
616 }
|
Chris@16
|
617 template <unsigned digits10>
|
Chris@16
|
618 inline void eval_divide(gmp_float<digits10>& result, unsigned long i)
|
Chris@16
|
619 {
|
Chris@16
|
620 if(i == 0)
|
Chris@16
|
621 BOOST_THROW_EXCEPTION(std::overflow_error("Division by zero."));
|
Chris@16
|
622 mpf_div_ui(result.data(), result.data(), i);
|
Chris@16
|
623 }
|
Chris@16
|
624 template <unsigned digits10>
|
Chris@16
|
625 inline void eval_add(gmp_float<digits10>& result, long i)
|
Chris@16
|
626 {
|
Chris@16
|
627 if(i > 0)
|
Chris@16
|
628 mpf_add_ui(result.data(), result.data(), i);
|
Chris@16
|
629 else
|
Chris@16
|
630 mpf_sub_ui(result.data(), result.data(), std::abs(i));
|
Chris@16
|
631 }
|
Chris@16
|
632 template <unsigned digits10>
|
Chris@16
|
633 inline void eval_subtract(gmp_float<digits10>& result, long i)
|
Chris@16
|
634 {
|
Chris@16
|
635 if(i > 0)
|
Chris@16
|
636 mpf_sub_ui(result.data(), result.data(), i);
|
Chris@16
|
637 else
|
Chris@16
|
638 mpf_add_ui(result.data(), result.data(), std::abs(i));
|
Chris@16
|
639 }
|
Chris@16
|
640 template <unsigned digits10>
|
Chris@16
|
641 inline void eval_multiply(gmp_float<digits10>& result, long i)
|
Chris@16
|
642 {
|
Chris@16
|
643 mpf_mul_ui(result.data(), result.data(), std::abs(i));
|
Chris@16
|
644 if(i < 0)
|
Chris@16
|
645 mpf_neg(result.data(), result.data());
|
Chris@16
|
646 }
|
Chris@16
|
647 template <unsigned digits10>
|
Chris@16
|
648 inline void eval_divide(gmp_float<digits10>& result, long i)
|
Chris@16
|
649 {
|
Chris@16
|
650 if(i == 0)
|
Chris@16
|
651 BOOST_THROW_EXCEPTION(std::overflow_error("Division by zero."));
|
Chris@16
|
652 mpf_div_ui(result.data(), result.data(), std::abs(i));
|
Chris@16
|
653 if(i < 0)
|
Chris@16
|
654 mpf_neg(result.data(), result.data());
|
Chris@16
|
655 }
|
Chris@16
|
656 //
|
Chris@16
|
657 // Specialised 3 arg versions of the basic operators:
|
Chris@16
|
658 //
|
Chris@16
|
659 template <unsigned D1, unsigned D2, unsigned D3>
|
Chris@16
|
660 inline void eval_add(gmp_float<D1>& a, const gmp_float<D2>& x, const gmp_float<D3>& y)
|
Chris@16
|
661 {
|
Chris@16
|
662 mpf_add(a.data(), x.data(), y.data());
|
Chris@16
|
663 }
|
Chris@16
|
664 template <unsigned D1, unsigned D2>
|
Chris@16
|
665 inline void eval_add(gmp_float<D1>& a, const gmp_float<D2>& x, unsigned long y)
|
Chris@16
|
666 {
|
Chris@16
|
667 mpf_add_ui(a.data(), x.data(), y);
|
Chris@16
|
668 }
|
Chris@16
|
669 template <unsigned D1, unsigned D2>
|
Chris@16
|
670 inline void eval_add(gmp_float<D1>& a, const gmp_float<D2>& x, long y)
|
Chris@16
|
671 {
|
Chris@16
|
672 if(y < 0)
|
Chris@101
|
673 mpf_sub_ui(a.data(), x.data(), boost::multiprecision::detail::unsigned_abs(y));
|
Chris@16
|
674 else
|
Chris@16
|
675 mpf_add_ui(a.data(), x.data(), y);
|
Chris@16
|
676 }
|
Chris@16
|
677 template <unsigned D1, unsigned D2>
|
Chris@16
|
678 inline void eval_add(gmp_float<D1>& a, unsigned long x, const gmp_float<D2>& y)
|
Chris@16
|
679 {
|
Chris@16
|
680 mpf_add_ui(a.data(), y.data(), x);
|
Chris@16
|
681 }
|
Chris@16
|
682 template <unsigned D1, unsigned D2>
|
Chris@16
|
683 inline void eval_add(gmp_float<D1>& a, long x, const gmp_float<D2>& y)
|
Chris@16
|
684 {
|
Chris@16
|
685 if(x < 0)
|
Chris@16
|
686 {
|
Chris@101
|
687 mpf_ui_sub(a.data(), boost::multiprecision::detail::unsigned_abs(x), y.data());
|
Chris@16
|
688 mpf_neg(a.data(), a.data());
|
Chris@16
|
689 }
|
Chris@16
|
690 else
|
Chris@16
|
691 mpf_add_ui(a.data(), y.data(), x);
|
Chris@16
|
692 }
|
Chris@16
|
693 template <unsigned D1, unsigned D2, unsigned D3>
|
Chris@16
|
694 inline void eval_subtract(gmp_float<D1>& a, const gmp_float<D2>& x, const gmp_float<D3>& y)
|
Chris@16
|
695 {
|
Chris@16
|
696 mpf_sub(a.data(), x.data(), y.data());
|
Chris@16
|
697 }
|
Chris@16
|
698 template <unsigned D1, unsigned D2>
|
Chris@16
|
699 inline void eval_subtract(gmp_float<D1>& a, const gmp_float<D2>& x, unsigned long y)
|
Chris@16
|
700 {
|
Chris@16
|
701 mpf_sub_ui(a.data(), x.data(), y);
|
Chris@16
|
702 }
|
Chris@16
|
703 template <unsigned D1, unsigned D2>
|
Chris@16
|
704 inline void eval_subtract(gmp_float<D1>& a, const gmp_float<D2>& x, long y)
|
Chris@16
|
705 {
|
Chris@16
|
706 if(y < 0)
|
Chris@101
|
707 mpf_add_ui(a.data(), x.data(), boost::multiprecision::detail::unsigned_abs(y));
|
Chris@16
|
708 else
|
Chris@16
|
709 mpf_sub_ui(a.data(), x.data(), y);
|
Chris@16
|
710 }
|
Chris@16
|
711 template <unsigned D1, unsigned D2>
|
Chris@16
|
712 inline void eval_subtract(gmp_float<D1>& a, unsigned long x, const gmp_float<D2>& y)
|
Chris@16
|
713 {
|
Chris@16
|
714 mpf_ui_sub(a.data(), x, y.data());
|
Chris@16
|
715 }
|
Chris@16
|
716 template <unsigned D1, unsigned D2>
|
Chris@16
|
717 inline void eval_subtract(gmp_float<D1>& a, long x, const gmp_float<D2>& y)
|
Chris@16
|
718 {
|
Chris@16
|
719 if(x < 0)
|
Chris@16
|
720 {
|
Chris@101
|
721 mpf_add_ui(a.data(), y.data(), boost::multiprecision::detail::unsigned_abs(x));
|
Chris@16
|
722 mpf_neg(a.data(), a.data());
|
Chris@16
|
723 }
|
Chris@16
|
724 else
|
Chris@16
|
725 mpf_ui_sub(a.data(), x, y.data());
|
Chris@16
|
726 }
|
Chris@16
|
727
|
Chris@16
|
728 template <unsigned D1, unsigned D2, unsigned D3>
|
Chris@16
|
729 inline void eval_multiply(gmp_float<D1>& a, const gmp_float<D2>& x, const gmp_float<D3>& y)
|
Chris@16
|
730 {
|
Chris@16
|
731 mpf_mul(a.data(), x.data(), y.data());
|
Chris@16
|
732 }
|
Chris@16
|
733 template <unsigned D1, unsigned D2>
|
Chris@16
|
734 inline void eval_multiply(gmp_float<D1>& a, const gmp_float<D2>& x, unsigned long y)
|
Chris@16
|
735 {
|
Chris@16
|
736 mpf_mul_ui(a.data(), x.data(), y);
|
Chris@16
|
737 }
|
Chris@16
|
738 template <unsigned D1, unsigned D2>
|
Chris@16
|
739 inline void eval_multiply(gmp_float<D1>& a, const gmp_float<D2>& x, long y)
|
Chris@16
|
740 {
|
Chris@16
|
741 if(y < 0)
|
Chris@16
|
742 {
|
Chris@101
|
743 mpf_mul_ui(a.data(), x.data(), boost::multiprecision::detail::unsigned_abs(y));
|
Chris@16
|
744 a.negate();
|
Chris@16
|
745 }
|
Chris@16
|
746 else
|
Chris@16
|
747 mpf_mul_ui(a.data(), x.data(), y);
|
Chris@16
|
748 }
|
Chris@16
|
749 template <unsigned D1, unsigned D2>
|
Chris@16
|
750 inline void eval_multiply(gmp_float<D1>& a, unsigned long x, const gmp_float<D2>& y)
|
Chris@16
|
751 {
|
Chris@16
|
752 mpf_mul_ui(a.data(), y.data(), x);
|
Chris@16
|
753 }
|
Chris@16
|
754 template <unsigned D1, unsigned D2>
|
Chris@16
|
755 inline void eval_multiply(gmp_float<D1>& a, long x, const gmp_float<D2>& y)
|
Chris@16
|
756 {
|
Chris@16
|
757 if(x < 0)
|
Chris@16
|
758 {
|
Chris@101
|
759 mpf_mul_ui(a.data(), y.data(), boost::multiprecision::detail::unsigned_abs(x));
|
Chris@16
|
760 mpf_neg(a.data(), a.data());
|
Chris@16
|
761 }
|
Chris@16
|
762 else
|
Chris@16
|
763 mpf_mul_ui(a.data(), y.data(), x);
|
Chris@16
|
764 }
|
Chris@16
|
765
|
Chris@16
|
766 template <unsigned D1, unsigned D2, unsigned D3>
|
Chris@16
|
767 inline void eval_divide(gmp_float<D1>& a, const gmp_float<D2>& x, const gmp_float<D3>& y)
|
Chris@16
|
768 {
|
Chris@16
|
769 if(eval_is_zero(y))
|
Chris@16
|
770 BOOST_THROW_EXCEPTION(std::overflow_error("Division by zero."));
|
Chris@16
|
771 mpf_div(a.data(), x.data(), y.data());
|
Chris@16
|
772 }
|
Chris@16
|
773 template <unsigned D1, unsigned D2>
|
Chris@16
|
774 inline void eval_divide(gmp_float<D1>& a, const gmp_float<D2>& x, unsigned long y)
|
Chris@16
|
775 {
|
Chris@16
|
776 if(y == 0)
|
Chris@16
|
777 BOOST_THROW_EXCEPTION(std::overflow_error("Division by zero."));
|
Chris@16
|
778 mpf_div_ui(a.data(), x.data(), y);
|
Chris@16
|
779 }
|
Chris@16
|
780 template <unsigned D1, unsigned D2>
|
Chris@16
|
781 inline void eval_divide(gmp_float<D1>& a, const gmp_float<D2>& x, long y)
|
Chris@16
|
782 {
|
Chris@16
|
783 if(y == 0)
|
Chris@16
|
784 BOOST_THROW_EXCEPTION(std::overflow_error("Division by zero."));
|
Chris@16
|
785 if(y < 0)
|
Chris@16
|
786 {
|
Chris@101
|
787 mpf_div_ui(a.data(), x.data(), boost::multiprecision::detail::unsigned_abs(y));
|
Chris@16
|
788 a.negate();
|
Chris@16
|
789 }
|
Chris@16
|
790 else
|
Chris@16
|
791 mpf_div_ui(a.data(), x.data(), y);
|
Chris@16
|
792 }
|
Chris@16
|
793 template <unsigned D1, unsigned D2>
|
Chris@16
|
794 inline void eval_divide(gmp_float<D1>& a, unsigned long x, const gmp_float<D2>& y)
|
Chris@16
|
795 {
|
Chris@16
|
796 if(eval_is_zero(y))
|
Chris@16
|
797 BOOST_THROW_EXCEPTION(std::overflow_error("Division by zero."));
|
Chris@16
|
798 mpf_ui_div(a.data(), x, y.data());
|
Chris@16
|
799 }
|
Chris@16
|
800 template <unsigned D1, unsigned D2>
|
Chris@16
|
801 inline void eval_divide(gmp_float<D1>& a, long x, const gmp_float<D2>& y)
|
Chris@16
|
802 {
|
Chris@16
|
803 if(eval_is_zero(y))
|
Chris@16
|
804 BOOST_THROW_EXCEPTION(std::overflow_error("Division by zero."));
|
Chris@16
|
805 if(x < 0)
|
Chris@16
|
806 {
|
Chris@101
|
807 mpf_ui_div(a.data(), boost::multiprecision::detail::unsigned_abs(x), y.data());
|
Chris@16
|
808 mpf_neg(a.data(), a.data());
|
Chris@16
|
809 }
|
Chris@16
|
810 else
|
Chris@16
|
811 mpf_ui_div(a.data(), x, y.data());
|
Chris@16
|
812 }
|
Chris@16
|
813
|
Chris@16
|
814 template <unsigned digits10>
|
Chris@16
|
815 inline int eval_get_sign(const gmp_float<digits10>& val) BOOST_NOEXCEPT
|
Chris@16
|
816 {
|
Chris@16
|
817 return mpf_sgn(val.data());
|
Chris@16
|
818 }
|
Chris@16
|
819
|
Chris@16
|
820 template <unsigned digits10>
|
Chris@16
|
821 inline void eval_convert_to(unsigned long* result, const gmp_float<digits10>& val) BOOST_NOEXCEPT
|
Chris@16
|
822 {
|
Chris@16
|
823 if(0 == mpf_fits_ulong_p(val.data()))
|
Chris@16
|
824 *result = (std::numeric_limits<unsigned long>::max)();
|
Chris@16
|
825 else
|
Chris@16
|
826 *result = mpf_get_ui(val.data());
|
Chris@16
|
827 }
|
Chris@16
|
828 template <unsigned digits10>
|
Chris@16
|
829 inline void eval_convert_to(long* result, const gmp_float<digits10>& val) BOOST_NOEXCEPT
|
Chris@16
|
830 {
|
Chris@16
|
831 if(0 == mpf_fits_slong_p(val.data()))
|
Chris@16
|
832 {
|
Chris@16
|
833 *result = (std::numeric_limits<unsigned long>::max)();
|
Chris@16
|
834 *result *= mpf_sgn(val.data());
|
Chris@16
|
835 }
|
Chris@16
|
836 else
|
Chris@16
|
837 *result = mpf_get_si(val.data());
|
Chris@16
|
838 }
|
Chris@16
|
839 template <unsigned digits10>
|
Chris@16
|
840 inline void eval_convert_to(double* result, const gmp_float<digits10>& val) BOOST_NOEXCEPT
|
Chris@16
|
841 {
|
Chris@16
|
842 *result = mpf_get_d(val.data());
|
Chris@16
|
843 }
|
Chris@16
|
844 #ifdef BOOST_HAS_LONG_LONG
|
Chris@16
|
845 template <unsigned digits10>
|
Chris@16
|
846 inline void eval_convert_to(long long* result, const gmp_float<digits10>& val)
|
Chris@16
|
847 {
|
Chris@16
|
848 gmp_float<digits10> t(val);
|
Chris@16
|
849 if(eval_get_sign(t) < 0)
|
Chris@16
|
850 t.negate();
|
Chris@16
|
851
|
Chris@16
|
852 long digits = std::numeric_limits<long long>::digits - std::numeric_limits<long>::digits;
|
Chris@16
|
853
|
Chris@16
|
854 if(digits > 0)
|
Chris@16
|
855 mpf_div_2exp(t.data(), t.data(), digits);
|
Chris@16
|
856
|
Chris@16
|
857 if(!mpf_fits_slong_p(t.data()))
|
Chris@16
|
858 {
|
Chris@16
|
859 if(eval_get_sign(val) < 0)
|
Chris@16
|
860 *result = (std::numeric_limits<long long>::min)();
|
Chris@16
|
861 else
|
Chris@16
|
862 *result = (std::numeric_limits<long long>::max)();
|
Chris@16
|
863 return;
|
Chris@16
|
864 };
|
Chris@16
|
865
|
Chris@16
|
866 *result = mpf_get_si(t.data());
|
Chris@16
|
867 while(digits > 0)
|
Chris@16
|
868 {
|
Chris@16
|
869 *result <<= digits;
|
Chris@16
|
870 digits -= std::numeric_limits<unsigned long>::digits;
|
Chris@16
|
871 mpf_mul_2exp(t.data(), t.data(), digits >= 0 ? std::numeric_limits<unsigned long>::digits : std::numeric_limits<unsigned long>::digits + digits);
|
Chris@16
|
872 unsigned long l = mpf_get_ui(t.data());
|
Chris@16
|
873 if(digits < 0)
|
Chris@16
|
874 l >>= -digits;
|
Chris@16
|
875 *result |= l;
|
Chris@16
|
876 }
|
Chris@16
|
877 if(eval_get_sign(val) < 0)
|
Chris@16
|
878 *result = -*result;
|
Chris@16
|
879 }
|
Chris@16
|
880 template <unsigned digits10>
|
Chris@16
|
881 inline void eval_convert_to(unsigned long long* result, const gmp_float<digits10>& val)
|
Chris@16
|
882 {
|
Chris@16
|
883 gmp_float<digits10> t(val);
|
Chris@16
|
884
|
Chris@16
|
885 long digits = std::numeric_limits<long long>::digits - std::numeric_limits<long>::digits;
|
Chris@16
|
886
|
Chris@16
|
887 if(digits > 0)
|
Chris@16
|
888 mpf_div_2exp(t.data(), t.data(), digits);
|
Chris@16
|
889
|
Chris@16
|
890 if(!mpf_fits_ulong_p(t.data()))
|
Chris@16
|
891 {
|
Chris@16
|
892 *result = (std::numeric_limits<long long>::max)();
|
Chris@16
|
893 return;
|
Chris@16
|
894 }
|
Chris@16
|
895
|
Chris@16
|
896 *result = mpf_get_ui(t.data());
|
Chris@16
|
897 while(digits > 0)
|
Chris@16
|
898 {
|
Chris@16
|
899 *result <<= digits;
|
Chris@16
|
900 digits -= std::numeric_limits<unsigned long>::digits;
|
Chris@16
|
901 mpf_mul_2exp(t.data(), t.data(), digits >= 0 ? std::numeric_limits<unsigned long>::digits : std::numeric_limits<unsigned long>::digits + digits);
|
Chris@16
|
902 unsigned long l = mpf_get_ui(t.data());
|
Chris@16
|
903 if(digits < 0)
|
Chris@16
|
904 l >>= -digits;
|
Chris@16
|
905 *result |= l;
|
Chris@16
|
906 }
|
Chris@16
|
907 }
|
Chris@16
|
908 #endif
|
Chris@16
|
909
|
Chris@16
|
910 //
|
Chris@16
|
911 // Native non-member operations:
|
Chris@16
|
912 //
|
Chris@16
|
913 template <unsigned Digits10>
|
Chris@16
|
914 inline void eval_sqrt(gmp_float<Digits10>& result, const gmp_float<Digits10>& val)
|
Chris@16
|
915 {
|
Chris@16
|
916 mpf_sqrt(result.data(), val.data());
|
Chris@16
|
917 }
|
Chris@16
|
918
|
Chris@16
|
919 template <unsigned Digits10>
|
Chris@16
|
920 inline void eval_abs(gmp_float<Digits10>& result, const gmp_float<Digits10>& val)
|
Chris@16
|
921 {
|
Chris@16
|
922 mpf_abs(result.data(), val.data());
|
Chris@16
|
923 }
|
Chris@16
|
924
|
Chris@16
|
925 template <unsigned Digits10>
|
Chris@16
|
926 inline void eval_fabs(gmp_float<Digits10>& result, const gmp_float<Digits10>& val)
|
Chris@16
|
927 {
|
Chris@16
|
928 mpf_abs(result.data(), val.data());
|
Chris@16
|
929 }
|
Chris@16
|
930 template <unsigned Digits10>
|
Chris@16
|
931 inline void eval_ceil(gmp_float<Digits10>& result, const gmp_float<Digits10>& val)
|
Chris@16
|
932 {
|
Chris@16
|
933 mpf_ceil(result.data(), val.data());
|
Chris@16
|
934 }
|
Chris@16
|
935 template <unsigned Digits10>
|
Chris@16
|
936 inline void eval_floor(gmp_float<Digits10>& result, const gmp_float<Digits10>& val)
|
Chris@16
|
937 {
|
Chris@16
|
938 mpf_floor(result.data(), val.data());
|
Chris@16
|
939 }
|
Chris@16
|
940 template <unsigned Digits10>
|
Chris@16
|
941 inline void eval_trunc(gmp_float<Digits10>& result, const gmp_float<Digits10>& val)
|
Chris@16
|
942 {
|
Chris@16
|
943 mpf_trunc(result.data(), val.data());
|
Chris@16
|
944 }
|
Chris@16
|
945 template <unsigned Digits10>
|
Chris@16
|
946 inline void eval_ldexp(gmp_float<Digits10>& result, const gmp_float<Digits10>& val, long e)
|
Chris@16
|
947 {
|
Chris@16
|
948 if(e > 0)
|
Chris@16
|
949 mpf_mul_2exp(result.data(), val.data(), e);
|
Chris@16
|
950 else if(e < 0)
|
Chris@16
|
951 mpf_div_2exp(result.data(), val.data(), -e);
|
Chris@16
|
952 else
|
Chris@16
|
953 result = val;
|
Chris@16
|
954 }
|
Chris@16
|
955 template <unsigned Digits10>
|
Chris@16
|
956 inline void eval_frexp(gmp_float<Digits10>& result, const gmp_float<Digits10>& val, int* e)
|
Chris@16
|
957 {
|
Chris@16
|
958 long v;
|
Chris@16
|
959 mpf_get_d_2exp(&v, val.data());
|
Chris@16
|
960 *e = v;
|
Chris@16
|
961 eval_ldexp(result, val, -v);
|
Chris@16
|
962 }
|
Chris@16
|
963 template <unsigned Digits10>
|
Chris@16
|
964 inline void eval_frexp(gmp_float<Digits10>& result, const gmp_float<Digits10>& val, long* e)
|
Chris@16
|
965 {
|
Chris@16
|
966 mpf_get_d_2exp(e, val.data());
|
Chris@16
|
967 eval_ldexp(result, val, -*e);
|
Chris@16
|
968 }
|
Chris@16
|
969
|
Chris@16
|
970 struct gmp_int
|
Chris@16
|
971 {
|
Chris@16
|
972 typedef mpl::list<long, long long> signed_types;
|
Chris@16
|
973 typedef mpl::list<unsigned long, unsigned long long> unsigned_types;
|
Chris@16
|
974 typedef mpl::list<double, long double> float_types;
|
Chris@16
|
975
|
Chris@16
|
976 gmp_int()
|
Chris@16
|
977 {
|
Chris@16
|
978 mpz_init(this->m_data);
|
Chris@16
|
979 }
|
Chris@16
|
980 gmp_int(const gmp_int& o)
|
Chris@16
|
981 {
|
Chris@16
|
982 if(o.m_data[0]._mp_d)
|
Chris@16
|
983 mpz_init_set(m_data, o.m_data);
|
Chris@16
|
984 else
|
Chris@16
|
985 mpz_init(this->m_data);
|
Chris@16
|
986 }
|
Chris@16
|
987 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
|
Chris@16
|
988 gmp_int(gmp_int&& o) BOOST_NOEXCEPT
|
Chris@16
|
989 {
|
Chris@16
|
990 m_data[0] = o.m_data[0];
|
Chris@16
|
991 o.m_data[0]._mp_d = 0;
|
Chris@16
|
992 }
|
Chris@16
|
993 #endif
|
Chris@16
|
994 explicit gmp_int(const mpf_t val)
|
Chris@16
|
995 {
|
Chris@16
|
996 mpz_init(this->m_data);
|
Chris@16
|
997 mpz_set_f(this->m_data, val);
|
Chris@16
|
998 }
|
Chris@16
|
999 gmp_int(const mpz_t val)
|
Chris@16
|
1000 {
|
Chris@16
|
1001 mpz_init_set(this->m_data, val);
|
Chris@16
|
1002 }
|
Chris@16
|
1003 explicit gmp_int(const mpq_t val)
|
Chris@16
|
1004 {
|
Chris@16
|
1005 mpz_init(this->m_data);
|
Chris@16
|
1006 mpz_set_q(this->m_data, val);
|
Chris@16
|
1007 }
|
Chris@16
|
1008 template <unsigned Digits10>
|
Chris@16
|
1009 explicit gmp_int(const gmp_float<Digits10>& o)
|
Chris@16
|
1010 {
|
Chris@16
|
1011 mpz_init(this->m_data);
|
Chris@16
|
1012 mpz_set_f(this->m_data, o.data());
|
Chris@16
|
1013 }
|
Chris@16
|
1014 explicit gmp_int(const gmp_rational& o);
|
Chris@16
|
1015 gmp_int& operator = (const gmp_int& o)
|
Chris@16
|
1016 {
|
Chris@16
|
1017 if(m_data[0]._mp_d == 0)
|
Chris@16
|
1018 mpz_init(this->m_data);
|
Chris@16
|
1019 mpz_set(m_data, o.m_data);
|
Chris@16
|
1020 return *this;
|
Chris@16
|
1021 }
|
Chris@16
|
1022 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
|
Chris@16
|
1023 gmp_int& operator = (gmp_int&& o) BOOST_NOEXCEPT
|
Chris@16
|
1024 {
|
Chris@16
|
1025 mpz_swap(m_data, o.m_data);
|
Chris@16
|
1026 return *this;
|
Chris@16
|
1027 }
|
Chris@16
|
1028 #endif
|
Chris@16
|
1029 gmp_int& operator = (unsigned long long i)
|
Chris@16
|
1030 {
|
Chris@16
|
1031 if(m_data[0]._mp_d == 0)
|
Chris@16
|
1032 mpz_init(this->m_data);
|
Chris@16
|
1033 unsigned long long mask = ((1uLL << std::numeric_limits<unsigned>::digits) - 1);
|
Chris@16
|
1034 unsigned shift = 0;
|
Chris@16
|
1035 mpz_t t;
|
Chris@16
|
1036 mpz_set_ui(m_data, 0);
|
Chris@16
|
1037 mpz_init_set_ui(t, 0);
|
Chris@16
|
1038 while(i)
|
Chris@16
|
1039 {
|
Chris@16
|
1040 mpz_set_ui(t, static_cast<unsigned>(i & mask));
|
Chris@16
|
1041 if(shift)
|
Chris@16
|
1042 mpz_mul_2exp(t, t, shift);
|
Chris@16
|
1043 mpz_add(m_data, m_data, t);
|
Chris@16
|
1044 shift += std::numeric_limits<unsigned>::digits;
|
Chris@16
|
1045 i >>= std::numeric_limits<unsigned>::digits;
|
Chris@16
|
1046 }
|
Chris@16
|
1047 mpz_clear(t);
|
Chris@16
|
1048 return *this;
|
Chris@16
|
1049 }
|
Chris@16
|
1050 gmp_int& operator = (long long i)
|
Chris@16
|
1051 {
|
Chris@16
|
1052 if(m_data[0]._mp_d == 0)
|
Chris@16
|
1053 mpz_init(this->m_data);
|
Chris@16
|
1054 bool neg = i < 0;
|
Chris@101
|
1055 *this = boost::multiprecision::detail::unsigned_abs(i);
|
Chris@16
|
1056 if(neg)
|
Chris@16
|
1057 mpz_neg(m_data, m_data);
|
Chris@16
|
1058 return *this;
|
Chris@16
|
1059 }
|
Chris@16
|
1060 gmp_int& operator = (unsigned long i)
|
Chris@16
|
1061 {
|
Chris@16
|
1062 if(m_data[0]._mp_d == 0)
|
Chris@16
|
1063 mpz_init(this->m_data);
|
Chris@16
|
1064 mpz_set_ui(m_data, i);
|
Chris@16
|
1065 return *this;
|
Chris@16
|
1066 }
|
Chris@16
|
1067 gmp_int& operator = (long i)
|
Chris@16
|
1068 {
|
Chris@16
|
1069 if(m_data[0]._mp_d == 0)
|
Chris@16
|
1070 mpz_init(this->m_data);
|
Chris@16
|
1071 mpz_set_si(m_data, i);
|
Chris@16
|
1072 return *this;
|
Chris@16
|
1073 }
|
Chris@16
|
1074 gmp_int& operator = (double d)
|
Chris@16
|
1075 {
|
Chris@16
|
1076 if(m_data[0]._mp_d == 0)
|
Chris@16
|
1077 mpz_init(this->m_data);
|
Chris@16
|
1078 mpz_set_d(m_data, d);
|
Chris@16
|
1079 return *this;
|
Chris@16
|
1080 }
|
Chris@16
|
1081 gmp_int& operator = (long double a)
|
Chris@16
|
1082 {
|
Chris@16
|
1083 using std::frexp;
|
Chris@16
|
1084 using std::ldexp;
|
Chris@16
|
1085 using std::floor;
|
Chris@16
|
1086
|
Chris@16
|
1087 if(m_data[0]._mp_d == 0)
|
Chris@16
|
1088 mpz_init(this->m_data);
|
Chris@16
|
1089
|
Chris@16
|
1090 if (a == 0) {
|
Chris@16
|
1091 mpz_set_si(m_data, 0);
|
Chris@16
|
1092 return *this;
|
Chris@16
|
1093 }
|
Chris@16
|
1094
|
Chris@16
|
1095 if (a == 1) {
|
Chris@16
|
1096 mpz_set_si(m_data, 1);
|
Chris@16
|
1097 return *this;
|
Chris@16
|
1098 }
|
Chris@16
|
1099
|
Chris@16
|
1100 BOOST_ASSERT(!(boost::math::isinf)(a));
|
Chris@16
|
1101 BOOST_ASSERT(!(boost::math::isnan)(a));
|
Chris@16
|
1102
|
Chris@16
|
1103 int e;
|
Chris@16
|
1104 long double f, term;
|
Chris@16
|
1105 mpz_set_ui(m_data, 0u);
|
Chris@16
|
1106
|
Chris@16
|
1107 f = frexp(a, &e);
|
Chris@16
|
1108
|
Chris@16
|
1109 static const int shift = std::numeric_limits<int>::digits - 1;
|
Chris@16
|
1110
|
Chris@16
|
1111 while(f)
|
Chris@16
|
1112 {
|
Chris@16
|
1113 // extract int sized bits from f:
|
Chris@16
|
1114 f = ldexp(f, shift);
|
Chris@16
|
1115 term = floor(f);
|
Chris@16
|
1116 e -= shift;
|
Chris@16
|
1117 mpz_mul_2exp(m_data, m_data, shift);
|
Chris@16
|
1118 if(term > 0)
|
Chris@16
|
1119 mpz_add_ui(m_data, m_data, static_cast<unsigned>(term));
|
Chris@16
|
1120 else
|
Chris@16
|
1121 mpz_sub_ui(m_data, m_data, static_cast<unsigned>(-term));
|
Chris@16
|
1122 f -= term;
|
Chris@16
|
1123 }
|
Chris@16
|
1124 if(e > 0)
|
Chris@16
|
1125 mpz_mul_2exp(m_data, m_data, e);
|
Chris@16
|
1126 else if(e < 0)
|
Chris@16
|
1127 mpz_div_2exp(m_data, m_data, -e);
|
Chris@16
|
1128 return *this;
|
Chris@16
|
1129 }
|
Chris@16
|
1130 gmp_int& operator = (const char* s)
|
Chris@16
|
1131 {
|
Chris@16
|
1132 if(m_data[0]._mp_d == 0)
|
Chris@16
|
1133 mpz_init(this->m_data);
|
Chris@16
|
1134 std::size_t n = s ? std::strlen(s) : 0;
|
Chris@16
|
1135 int radix = 10;
|
Chris@16
|
1136 if(n && (*s == '0'))
|
Chris@16
|
1137 {
|
Chris@16
|
1138 if((n > 1) && ((s[1] == 'x') || (s[1] == 'X')))
|
Chris@16
|
1139 {
|
Chris@16
|
1140 radix = 16;
|
Chris@16
|
1141 s +=2;
|
Chris@16
|
1142 n -= 2;
|
Chris@16
|
1143 }
|
Chris@16
|
1144 else
|
Chris@16
|
1145 {
|
Chris@16
|
1146 radix = 8;
|
Chris@16
|
1147 n -= 1;
|
Chris@16
|
1148 }
|
Chris@16
|
1149 }
|
Chris@16
|
1150 if(n)
|
Chris@16
|
1151 {
|
Chris@16
|
1152 if(0 != mpz_set_str(m_data, s, radix))
|
Chris@16
|
1153 BOOST_THROW_EXCEPTION(std::runtime_error(std::string("The string \"") + s + std::string("\"could not be interpreted as a valid integer.")));
|
Chris@16
|
1154 }
|
Chris@16
|
1155 else
|
Chris@16
|
1156 mpz_set_ui(m_data, 0);
|
Chris@16
|
1157 return *this;
|
Chris@16
|
1158 }
|
Chris@16
|
1159 gmp_int& operator=(const mpf_t val)
|
Chris@16
|
1160 {
|
Chris@16
|
1161 if(m_data[0]._mp_d == 0)
|
Chris@16
|
1162 mpz_init(this->m_data);
|
Chris@16
|
1163 mpz_set_f(this->m_data, val);
|
Chris@16
|
1164 return *this;
|
Chris@16
|
1165 }
|
Chris@16
|
1166 gmp_int& operator=(const mpz_t val)
|
Chris@16
|
1167 {
|
Chris@16
|
1168 if(m_data[0]._mp_d == 0)
|
Chris@16
|
1169 mpz_init(this->m_data);
|
Chris@16
|
1170 mpz_set(this->m_data, val);
|
Chris@16
|
1171 return *this;
|
Chris@16
|
1172 }
|
Chris@16
|
1173 gmp_int& operator=(const mpq_t val)
|
Chris@16
|
1174 {
|
Chris@16
|
1175 if(m_data[0]._mp_d == 0)
|
Chris@16
|
1176 mpz_init(this->m_data);
|
Chris@16
|
1177 mpz_set_q(this->m_data, val);
|
Chris@16
|
1178 return *this;
|
Chris@16
|
1179 }
|
Chris@16
|
1180 template <unsigned Digits10>
|
Chris@16
|
1181 gmp_int& operator=(const gmp_float<Digits10>& o)
|
Chris@16
|
1182 {
|
Chris@16
|
1183 if(m_data[0]._mp_d == 0)
|
Chris@16
|
1184 mpz_init(this->m_data);
|
Chris@16
|
1185 mpz_set_f(this->m_data, o.data());
|
Chris@16
|
1186 return *this;
|
Chris@16
|
1187 }
|
Chris@16
|
1188 gmp_int& operator=(const gmp_rational& o);
|
Chris@16
|
1189 void swap(gmp_int& o)
|
Chris@16
|
1190 {
|
Chris@16
|
1191 mpz_swap(m_data, o.m_data);
|
Chris@16
|
1192 }
|
Chris@16
|
1193 std::string str(std::streamsize /*digits*/, std::ios_base::fmtflags f)const
|
Chris@16
|
1194 {
|
Chris@16
|
1195 BOOST_ASSERT(m_data[0]._mp_d);
|
Chris@16
|
1196
|
Chris@16
|
1197 int base = 10;
|
Chris@16
|
1198 if((f & std::ios_base::oct) == std::ios_base::oct)
|
Chris@16
|
1199 base = 8;
|
Chris@16
|
1200 else if((f & std::ios_base::hex) == std::ios_base::hex)
|
Chris@16
|
1201 base = 16;
|
Chris@16
|
1202 //
|
Chris@16
|
1203 // sanity check, bases 8 and 16 are only available for positive numbers:
|
Chris@16
|
1204 //
|
Chris@16
|
1205 if((base != 10) && (mpz_sgn(m_data) < 0))
|
Chris@16
|
1206 BOOST_THROW_EXCEPTION(std::runtime_error("Formatted output in bases 8 or 16 is only available for positive numbers"));
|
Chris@16
|
1207 void *(*alloc_func_ptr) (size_t);
|
Chris@16
|
1208 void *(*realloc_func_ptr) (void *, size_t, size_t);
|
Chris@16
|
1209 void (*free_func_ptr) (void *, size_t);
|
Chris@16
|
1210 const char* ps = mpz_get_str (0, base, m_data);
|
Chris@16
|
1211 std::string s = ps;
|
Chris@16
|
1212 mp_get_memory_functions(&alloc_func_ptr, &realloc_func_ptr, &free_func_ptr);
|
Chris@16
|
1213 (*free_func_ptr)((void*)ps, std::strlen(ps) + 1);
|
Chris@16
|
1214
|
Chris@16
|
1215 if((base != 10) && (f & std::ios_base::showbase))
|
Chris@16
|
1216 {
|
Chris@16
|
1217 int pos = s[0] == '-' ? 1 : 0;
|
Chris@16
|
1218 const char* pp = base == 8 ? "0" : "0x";
|
Chris@101
|
1219 s.insert(static_cast<std::string::size_type>(pos), pp);
|
Chris@16
|
1220 }
|
Chris@16
|
1221 if((f & std::ios_base::showpos) && (s[0] != '-'))
|
Chris@101
|
1222 s.insert(static_cast<std::string::size_type>(0), 1, '+');
|
Chris@16
|
1223
|
Chris@16
|
1224 return s;
|
Chris@16
|
1225 }
|
Chris@16
|
1226 ~gmp_int() BOOST_NOEXCEPT
|
Chris@16
|
1227 {
|
Chris@16
|
1228 if(m_data[0]._mp_d)
|
Chris@16
|
1229 mpz_clear(m_data);
|
Chris@16
|
1230 }
|
Chris@16
|
1231 void negate() BOOST_NOEXCEPT
|
Chris@16
|
1232 {
|
Chris@16
|
1233 BOOST_ASSERT(m_data[0]._mp_d);
|
Chris@16
|
1234 mpz_neg(m_data, m_data);
|
Chris@16
|
1235 }
|
Chris@16
|
1236 int compare(const gmp_int& o)const BOOST_NOEXCEPT
|
Chris@16
|
1237 {
|
Chris@16
|
1238 BOOST_ASSERT(m_data[0]._mp_d && o.m_data[0]._mp_d);
|
Chris@16
|
1239 return mpz_cmp(m_data, o.m_data);
|
Chris@16
|
1240 }
|
Chris@16
|
1241 int compare(long i)const BOOST_NOEXCEPT
|
Chris@16
|
1242 {
|
Chris@16
|
1243 BOOST_ASSERT(m_data[0]._mp_d);
|
Chris@16
|
1244 return mpz_cmp_si(m_data, i);
|
Chris@16
|
1245 }
|
Chris@16
|
1246 int compare(unsigned long i)const BOOST_NOEXCEPT
|
Chris@16
|
1247 {
|
Chris@16
|
1248 BOOST_ASSERT(m_data[0]._mp_d);
|
Chris@16
|
1249 return mpz_cmp_ui(m_data, i);
|
Chris@16
|
1250 }
|
Chris@16
|
1251 template <class V>
|
Chris@16
|
1252 int compare(V v)const
|
Chris@16
|
1253 {
|
Chris@16
|
1254 gmp_int d;
|
Chris@16
|
1255 d = v;
|
Chris@16
|
1256 return compare(d);
|
Chris@16
|
1257 }
|
Chris@16
|
1258 mpz_t& data() BOOST_NOEXCEPT
|
Chris@16
|
1259 {
|
Chris@16
|
1260 BOOST_ASSERT(m_data[0]._mp_d);
|
Chris@16
|
1261 return m_data;
|
Chris@16
|
1262 }
|
Chris@16
|
1263 const mpz_t& data()const BOOST_NOEXCEPT
|
Chris@16
|
1264 {
|
Chris@16
|
1265 BOOST_ASSERT(m_data[0]._mp_d);
|
Chris@16
|
1266 return m_data;
|
Chris@16
|
1267 }
|
Chris@16
|
1268 protected:
|
Chris@16
|
1269 mpz_t m_data;
|
Chris@16
|
1270 };
|
Chris@16
|
1271
|
Chris@16
|
1272 template <class T>
|
Chris@16
|
1273 inline typename enable_if<is_arithmetic<T>, bool>::type eval_eq(const gmp_int& a, const T& b)
|
Chris@16
|
1274 {
|
Chris@16
|
1275 return a.compare(b) == 0;
|
Chris@16
|
1276 }
|
Chris@16
|
1277 template <class T>
|
Chris@16
|
1278 inline typename enable_if<is_arithmetic<T>, bool>::type eval_lt(const gmp_int& a, const T& b)
|
Chris@16
|
1279 {
|
Chris@16
|
1280 return a.compare(b) < 0;
|
Chris@16
|
1281 }
|
Chris@16
|
1282 template <class T>
|
Chris@16
|
1283 inline typename enable_if<is_arithmetic<T>, bool>::type eval_gt(const gmp_int& a, const T& b)
|
Chris@16
|
1284 {
|
Chris@16
|
1285 return a.compare(b) > 0;
|
Chris@16
|
1286 }
|
Chris@16
|
1287
|
Chris@16
|
1288 inline bool eval_is_zero(const gmp_int& val)
|
Chris@16
|
1289 {
|
Chris@16
|
1290 return mpz_sgn(val.data()) == 0;
|
Chris@16
|
1291 }
|
Chris@16
|
1292 inline void eval_add(gmp_int& t, const gmp_int& o)
|
Chris@16
|
1293 {
|
Chris@16
|
1294 mpz_add(t.data(), t.data(), o.data());
|
Chris@16
|
1295 }
|
Chris@16
|
1296 inline void eval_multiply_add(gmp_int& t, const gmp_int& a, const gmp_int& b)
|
Chris@16
|
1297 {
|
Chris@16
|
1298 mpz_addmul(t.data(), a.data(), b.data());
|
Chris@16
|
1299 }
|
Chris@16
|
1300 inline void eval_multiply_subtract(gmp_int& t, const gmp_int& a, const gmp_int& b)
|
Chris@16
|
1301 {
|
Chris@16
|
1302 mpz_submul(t.data(), a.data(), b.data());
|
Chris@16
|
1303 }
|
Chris@16
|
1304 inline void eval_subtract(gmp_int& t, const gmp_int& o)
|
Chris@16
|
1305 {
|
Chris@16
|
1306 mpz_sub(t.data(), t.data(), o.data());
|
Chris@16
|
1307 }
|
Chris@16
|
1308 inline void eval_multiply(gmp_int& t, const gmp_int& o)
|
Chris@16
|
1309 {
|
Chris@16
|
1310 mpz_mul(t.data(), t.data(), o.data());
|
Chris@16
|
1311 }
|
Chris@16
|
1312 inline void eval_divide(gmp_int& t, const gmp_int& o)
|
Chris@16
|
1313 {
|
Chris@16
|
1314 if(eval_is_zero(o))
|
Chris@16
|
1315 BOOST_THROW_EXCEPTION(std::overflow_error("Division by zero."));
|
Chris@16
|
1316 mpz_tdiv_q(t.data(), t.data(), o.data());
|
Chris@16
|
1317 }
|
Chris@16
|
1318 inline void eval_modulus(gmp_int& t, const gmp_int& o)
|
Chris@16
|
1319 {
|
Chris@16
|
1320 mpz_tdiv_r(t.data(), t.data(), o.data());
|
Chris@16
|
1321 }
|
Chris@16
|
1322 inline void eval_add(gmp_int& t, unsigned long i)
|
Chris@16
|
1323 {
|
Chris@16
|
1324 mpz_add_ui(t.data(), t.data(), i);
|
Chris@16
|
1325 }
|
Chris@16
|
1326 inline void eval_multiply_add(gmp_int& t, const gmp_int& a, unsigned long i)
|
Chris@16
|
1327 {
|
Chris@16
|
1328 mpz_addmul_ui(t.data(), a.data(), i);
|
Chris@16
|
1329 }
|
Chris@16
|
1330 inline void eval_multiply_subtract(gmp_int& t, const gmp_int& a, unsigned long i)
|
Chris@16
|
1331 {
|
Chris@16
|
1332 mpz_submul_ui(t.data(), a.data(), i);
|
Chris@16
|
1333 }
|
Chris@16
|
1334 inline void eval_subtract(gmp_int& t, unsigned long i)
|
Chris@16
|
1335 {
|
Chris@16
|
1336 mpz_sub_ui(t.data(), t.data(), i);
|
Chris@16
|
1337 }
|
Chris@16
|
1338 inline void eval_multiply(gmp_int& t, unsigned long i)
|
Chris@16
|
1339 {
|
Chris@16
|
1340 mpz_mul_ui(t.data(), t.data(), i);
|
Chris@16
|
1341 }
|
Chris@16
|
1342 inline void eval_modulus(gmp_int& t, unsigned long i)
|
Chris@16
|
1343 {
|
Chris@16
|
1344 mpz_tdiv_r_ui(t.data(), t.data(), i);
|
Chris@16
|
1345 }
|
Chris@16
|
1346 inline void eval_divide(gmp_int& t, unsigned long i)
|
Chris@16
|
1347 {
|
Chris@16
|
1348 if(i == 0)
|
Chris@16
|
1349 BOOST_THROW_EXCEPTION(std::overflow_error("Division by zero."));
|
Chris@16
|
1350 mpz_tdiv_q_ui(t.data(), t.data(), i);
|
Chris@16
|
1351 }
|
Chris@16
|
1352 inline void eval_add(gmp_int& t, long i)
|
Chris@16
|
1353 {
|
Chris@16
|
1354 if(i > 0)
|
Chris@16
|
1355 mpz_add_ui(t.data(), t.data(), i);
|
Chris@16
|
1356 else
|
Chris@101
|
1357 mpz_sub_ui(t.data(), t.data(), boost::multiprecision::detail::unsigned_abs(i));
|
Chris@16
|
1358 }
|
Chris@16
|
1359 inline void eval_multiply_add(gmp_int& t, const gmp_int& a, long i)
|
Chris@16
|
1360 {
|
Chris@16
|
1361 if(i > 0)
|
Chris@16
|
1362 mpz_addmul_ui(t.data(), a.data(), i);
|
Chris@16
|
1363 else
|
Chris@101
|
1364 mpz_submul_ui(t.data(), a.data(), boost::multiprecision::detail::unsigned_abs(i));
|
Chris@16
|
1365 }
|
Chris@16
|
1366 inline void eval_multiply_subtract(gmp_int& t, const gmp_int& a, long i)
|
Chris@16
|
1367 {
|
Chris@16
|
1368 if(i > 0)
|
Chris@16
|
1369 mpz_submul_ui(t.data(), a.data(), i);
|
Chris@16
|
1370 else
|
Chris@101
|
1371 mpz_addmul_ui(t.data(), a.data(), boost::multiprecision::detail::unsigned_abs(i));
|
Chris@16
|
1372 }
|
Chris@16
|
1373 inline void eval_subtract(gmp_int& t, long i)
|
Chris@16
|
1374 {
|
Chris@16
|
1375 if(i > 0)
|
Chris@16
|
1376 mpz_sub_ui(t.data(), t.data(), i);
|
Chris@16
|
1377 else
|
Chris@101
|
1378 mpz_add_ui(t.data(), t.data(), boost::multiprecision::detail::unsigned_abs(i));
|
Chris@16
|
1379 }
|
Chris@16
|
1380 inline void eval_multiply(gmp_int& t, long i)
|
Chris@16
|
1381 {
|
Chris@16
|
1382 mpz_mul_ui(t.data(), t.data(), std::abs(i));
|
Chris@16
|
1383 if(i < 0)
|
Chris@16
|
1384 mpz_neg(t.data(), t.data());
|
Chris@16
|
1385 }
|
Chris@16
|
1386 inline void eval_modulus(gmp_int& t, long i)
|
Chris@16
|
1387 {
|
Chris@16
|
1388 mpz_tdiv_r_ui(t.data(), t.data(), std::abs(i));
|
Chris@16
|
1389 }
|
Chris@16
|
1390 inline void eval_divide(gmp_int& t, long i)
|
Chris@16
|
1391 {
|
Chris@16
|
1392 if(i == 0)
|
Chris@16
|
1393 BOOST_THROW_EXCEPTION(std::overflow_error("Division by zero."));
|
Chris@16
|
1394 mpz_tdiv_q_ui(t.data(), t.data(), std::abs(i));
|
Chris@16
|
1395 if(i < 0)
|
Chris@16
|
1396 mpz_neg(t.data(), t.data());
|
Chris@16
|
1397 }
|
Chris@16
|
1398 template <class UI>
|
Chris@16
|
1399 inline void eval_left_shift(gmp_int& t, UI i)
|
Chris@16
|
1400 {
|
Chris@16
|
1401 mpz_mul_2exp(t.data(), t.data(), static_cast<unsigned long>(i));
|
Chris@16
|
1402 }
|
Chris@16
|
1403 template <class UI>
|
Chris@16
|
1404 inline void eval_right_shift(gmp_int& t, UI i)
|
Chris@16
|
1405 {
|
Chris@16
|
1406 mpz_fdiv_q_2exp(t.data(), t.data(), static_cast<unsigned long>(i));
|
Chris@16
|
1407 }
|
Chris@16
|
1408 template <class UI>
|
Chris@16
|
1409 inline void eval_left_shift(gmp_int& t, const gmp_int& v, UI i)
|
Chris@16
|
1410 {
|
Chris@16
|
1411 mpz_mul_2exp(t.data(), v.data(), static_cast<unsigned long>(i));
|
Chris@16
|
1412 }
|
Chris@16
|
1413 template <class UI>
|
Chris@16
|
1414 inline void eval_right_shift(gmp_int& t, const gmp_int& v, UI i)
|
Chris@16
|
1415 {
|
Chris@16
|
1416 mpz_fdiv_q_2exp(t.data(), v.data(), static_cast<unsigned long>(i));
|
Chris@16
|
1417 }
|
Chris@16
|
1418
|
Chris@16
|
1419 inline void eval_bitwise_and(gmp_int& result, const gmp_int& v)
|
Chris@16
|
1420 {
|
Chris@16
|
1421 mpz_and(result.data(), result.data(), v.data());
|
Chris@16
|
1422 }
|
Chris@16
|
1423
|
Chris@16
|
1424 inline void eval_bitwise_or(gmp_int& result, const gmp_int& v)
|
Chris@16
|
1425 {
|
Chris@16
|
1426 mpz_ior(result.data(), result.data(), v.data());
|
Chris@16
|
1427 }
|
Chris@16
|
1428
|
Chris@16
|
1429 inline void eval_bitwise_xor(gmp_int& result, const gmp_int& v)
|
Chris@16
|
1430 {
|
Chris@16
|
1431 mpz_xor(result.data(), result.data(), v.data());
|
Chris@16
|
1432 }
|
Chris@16
|
1433
|
Chris@16
|
1434 inline void eval_add(gmp_int& t, const gmp_int& p, const gmp_int& o)
|
Chris@16
|
1435 {
|
Chris@16
|
1436 mpz_add(t.data(), p.data(), o.data());
|
Chris@16
|
1437 }
|
Chris@16
|
1438 inline void eval_subtract(gmp_int& t, const gmp_int& p, const gmp_int& o)
|
Chris@16
|
1439 {
|
Chris@16
|
1440 mpz_sub(t.data(), p.data(), o.data());
|
Chris@16
|
1441 }
|
Chris@16
|
1442 inline void eval_multiply(gmp_int& t, const gmp_int& p, const gmp_int& o)
|
Chris@16
|
1443 {
|
Chris@16
|
1444 mpz_mul(t.data(), p.data(), o.data());
|
Chris@16
|
1445 }
|
Chris@16
|
1446 inline void eval_divide(gmp_int& t, const gmp_int& p, const gmp_int& o)
|
Chris@16
|
1447 {
|
Chris@16
|
1448 if(eval_is_zero(o))
|
Chris@16
|
1449 BOOST_THROW_EXCEPTION(std::overflow_error("Division by zero."));
|
Chris@16
|
1450 mpz_tdiv_q(t.data(), p.data(), o.data());
|
Chris@16
|
1451 }
|
Chris@16
|
1452 inline void eval_modulus(gmp_int& t, const gmp_int& p, const gmp_int& o)
|
Chris@16
|
1453 {
|
Chris@16
|
1454 mpz_tdiv_r(t.data(), p.data(), o.data());
|
Chris@16
|
1455 }
|
Chris@16
|
1456 inline void eval_add(gmp_int& t, const gmp_int& p, unsigned long i)
|
Chris@16
|
1457 {
|
Chris@16
|
1458 mpz_add_ui(t.data(), p.data(), i);
|
Chris@16
|
1459 }
|
Chris@16
|
1460 inline void eval_subtract(gmp_int& t, const gmp_int& p, unsigned long i)
|
Chris@16
|
1461 {
|
Chris@16
|
1462 mpz_sub_ui(t.data(), p.data(), i);
|
Chris@16
|
1463 }
|
Chris@16
|
1464 inline void eval_multiply(gmp_int& t, const gmp_int& p, unsigned long i)
|
Chris@16
|
1465 {
|
Chris@16
|
1466 mpz_mul_ui(t.data(), p.data(), i);
|
Chris@16
|
1467 }
|
Chris@16
|
1468 inline void eval_modulus(gmp_int& t, const gmp_int& p, unsigned long i)
|
Chris@16
|
1469 {
|
Chris@16
|
1470 mpz_tdiv_r_ui(t.data(), p.data(), i);
|
Chris@16
|
1471 }
|
Chris@16
|
1472 inline void eval_divide(gmp_int& t, const gmp_int& p, unsigned long i)
|
Chris@16
|
1473 {
|
Chris@16
|
1474 if(i == 0)
|
Chris@16
|
1475 BOOST_THROW_EXCEPTION(std::overflow_error("Division by zero."));
|
Chris@16
|
1476 mpz_tdiv_q_ui(t.data(), p.data(), i);
|
Chris@16
|
1477 }
|
Chris@16
|
1478 inline void eval_add(gmp_int& t, const gmp_int& p, long i)
|
Chris@16
|
1479 {
|
Chris@16
|
1480 if(i > 0)
|
Chris@16
|
1481 mpz_add_ui(t.data(), p.data(), i);
|
Chris@16
|
1482 else
|
Chris@101
|
1483 mpz_sub_ui(t.data(), p.data(), boost::multiprecision::detail::unsigned_abs(i));
|
Chris@16
|
1484 }
|
Chris@16
|
1485 inline void eval_subtract(gmp_int& t, const gmp_int& p, long i)
|
Chris@16
|
1486 {
|
Chris@16
|
1487 if(i > 0)
|
Chris@16
|
1488 mpz_sub_ui(t.data(), p.data(), i);
|
Chris@16
|
1489 else
|
Chris@101
|
1490 mpz_add_ui(t.data(), p.data(), boost::multiprecision::detail::unsigned_abs(i));
|
Chris@16
|
1491 }
|
Chris@16
|
1492 inline void eval_multiply(gmp_int& t, const gmp_int& p, long i)
|
Chris@16
|
1493 {
|
Chris@16
|
1494 mpz_mul_ui(t.data(), p.data(), std::abs(i));
|
Chris@16
|
1495 if(i < 0)
|
Chris@16
|
1496 mpz_neg(t.data(), t.data());
|
Chris@16
|
1497 }
|
Chris@16
|
1498 inline void eval_modulus(gmp_int& t, const gmp_int& p, long i)
|
Chris@16
|
1499 {
|
Chris@16
|
1500 mpz_tdiv_r_ui(t.data(), p.data(), std::abs(i));
|
Chris@16
|
1501 }
|
Chris@16
|
1502 inline void eval_divide(gmp_int& t, const gmp_int& p, long i)
|
Chris@16
|
1503 {
|
Chris@16
|
1504 if(i == 0)
|
Chris@16
|
1505 BOOST_THROW_EXCEPTION(std::overflow_error("Division by zero."));
|
Chris@16
|
1506 mpz_tdiv_q_ui(t.data(), p.data(), std::abs(i));
|
Chris@16
|
1507 if(i < 0)
|
Chris@16
|
1508 mpz_neg(t.data(), t.data());
|
Chris@16
|
1509 }
|
Chris@16
|
1510
|
Chris@16
|
1511 inline void eval_bitwise_and(gmp_int& result, const gmp_int& u, const gmp_int& v)
|
Chris@16
|
1512 {
|
Chris@16
|
1513 mpz_and(result.data(), u.data(), v.data());
|
Chris@16
|
1514 }
|
Chris@16
|
1515
|
Chris@16
|
1516 inline void eval_bitwise_or(gmp_int& result, const gmp_int& u, const gmp_int& v)
|
Chris@16
|
1517 {
|
Chris@16
|
1518 mpz_ior(result.data(), u.data(), v.data());
|
Chris@16
|
1519 }
|
Chris@16
|
1520
|
Chris@16
|
1521 inline void eval_bitwise_xor(gmp_int& result, const gmp_int& u, const gmp_int& v)
|
Chris@16
|
1522 {
|
Chris@16
|
1523 mpz_xor(result.data(), u.data(), v.data());
|
Chris@16
|
1524 }
|
Chris@16
|
1525
|
Chris@16
|
1526 inline void eval_complement(gmp_int& result, const gmp_int& u)
|
Chris@16
|
1527 {
|
Chris@16
|
1528 mpz_com(result.data(), u.data());
|
Chris@16
|
1529 }
|
Chris@16
|
1530
|
Chris@16
|
1531 inline int eval_get_sign(const gmp_int& val)
|
Chris@16
|
1532 {
|
Chris@16
|
1533 return mpz_sgn(val.data());
|
Chris@16
|
1534 }
|
Chris@16
|
1535 inline void eval_convert_to(unsigned long* result, const gmp_int& val)
|
Chris@16
|
1536 {
|
Chris@16
|
1537 if(0 == mpz_fits_ulong_p(val.data()))
|
Chris@16
|
1538 {
|
Chris@16
|
1539 *result = (std::numeric_limits<unsigned long>::max)();
|
Chris@16
|
1540 }
|
Chris@16
|
1541 else
|
Chris@16
|
1542 *result = mpz_get_ui(val.data());
|
Chris@16
|
1543 }
|
Chris@16
|
1544 inline void eval_convert_to(long* result, const gmp_int& val)
|
Chris@16
|
1545 {
|
Chris@16
|
1546 if(0 == mpz_fits_slong_p(val.data()))
|
Chris@16
|
1547 {
|
Chris@16
|
1548 *result = (std::numeric_limits<unsigned long>::max)();
|
Chris@16
|
1549 *result *= mpz_sgn(val.data());
|
Chris@16
|
1550 }
|
Chris@16
|
1551 else
|
Chris@16
|
1552 *result = mpz_get_si(val.data());
|
Chris@16
|
1553 }
|
Chris@16
|
1554 inline void eval_convert_to(double* result, const gmp_int& val)
|
Chris@16
|
1555 {
|
Chris@16
|
1556 *result = mpz_get_d(val.data());
|
Chris@16
|
1557 }
|
Chris@16
|
1558
|
Chris@16
|
1559 inline void eval_abs(gmp_int& result, const gmp_int& val)
|
Chris@16
|
1560 {
|
Chris@16
|
1561 mpz_abs(result.data(), val.data());
|
Chris@16
|
1562 }
|
Chris@16
|
1563
|
Chris@16
|
1564 inline void eval_gcd(gmp_int& result, const gmp_int& a, const gmp_int& b)
|
Chris@16
|
1565 {
|
Chris@16
|
1566 mpz_gcd(result.data(), a.data(), b.data());
|
Chris@16
|
1567 }
|
Chris@16
|
1568 inline void eval_lcm(gmp_int& result, const gmp_int& a, const gmp_int& b)
|
Chris@16
|
1569 {
|
Chris@16
|
1570 mpz_lcm(result.data(), a.data(), b.data());
|
Chris@16
|
1571 }
|
Chris@16
|
1572 template <class I>
|
Chris@16
|
1573 inline typename enable_if_c<(is_unsigned<I>::value && (sizeof(I) <= sizeof(unsigned long)))>::type eval_gcd(gmp_int& result, const gmp_int& a, const I b)
|
Chris@16
|
1574 {
|
Chris@16
|
1575 mpz_gcd_ui(result.data(), a.data(), b);
|
Chris@16
|
1576 }
|
Chris@16
|
1577 template <class I>
|
Chris@16
|
1578 inline typename enable_if_c<(is_unsigned<I>::value && (sizeof(I) <= sizeof(unsigned long)))>::type eval_lcm(gmp_int& result, const gmp_int& a, const I b)
|
Chris@16
|
1579 {
|
Chris@16
|
1580 mpz_lcm_ui(result.data(), a.data(), b);
|
Chris@16
|
1581 }
|
Chris@16
|
1582 template <class I>
|
Chris@16
|
1583 inline typename enable_if_c<(is_signed<I>::value && (sizeof(I) <= sizeof(long)))>::type eval_gcd(gmp_int& result, const gmp_int& a, const I b)
|
Chris@16
|
1584 {
|
Chris@16
|
1585 mpz_gcd_ui(result.data(), a.data(), std::abs(b));
|
Chris@16
|
1586 }
|
Chris@16
|
1587 template <class I>
|
Chris@16
|
1588 inline typename enable_if_c<is_signed<I>::value && ((sizeof(I) <= sizeof(long)))>::type eval_lcm(gmp_int& result, const gmp_int& a, const I b)
|
Chris@16
|
1589 {
|
Chris@16
|
1590 mpz_lcm_ui(result.data(), a.data(), std::abs(b));
|
Chris@16
|
1591 }
|
Chris@16
|
1592
|
Chris@16
|
1593 inline void eval_integer_sqrt(gmp_int& s, gmp_int& r, const gmp_int& x)
|
Chris@16
|
1594 {
|
Chris@16
|
1595 mpz_sqrtrem(s.data(), r.data(), x.data());
|
Chris@16
|
1596 }
|
Chris@16
|
1597
|
Chris@16
|
1598 inline unsigned eval_lsb(const gmp_int& val)
|
Chris@16
|
1599 {
|
Chris@16
|
1600 int c = eval_get_sign(val);
|
Chris@16
|
1601 if(c == 0)
|
Chris@16
|
1602 {
|
Chris@16
|
1603 BOOST_THROW_EXCEPTION(std::range_error("No bits were set in the operand."));
|
Chris@16
|
1604 }
|
Chris@16
|
1605 if(c < 0)
|
Chris@16
|
1606 {
|
Chris@16
|
1607 BOOST_THROW_EXCEPTION(std::range_error("Testing individual bits in negative values is not supported - results are undefined."));
|
Chris@16
|
1608 }
|
Chris@16
|
1609 return mpz_scan1(val.data(), 0);
|
Chris@16
|
1610 }
|
Chris@16
|
1611
|
Chris@16
|
1612 inline unsigned eval_msb(const gmp_int& val)
|
Chris@16
|
1613 {
|
Chris@16
|
1614 int c = eval_get_sign(val);
|
Chris@16
|
1615 if(c == 0)
|
Chris@16
|
1616 {
|
Chris@16
|
1617 BOOST_THROW_EXCEPTION(std::range_error("No bits were set in the operand."));
|
Chris@16
|
1618 }
|
Chris@16
|
1619 if(c < 0)
|
Chris@16
|
1620 {
|
Chris@16
|
1621 BOOST_THROW_EXCEPTION(std::range_error("Testing individual bits in negative values is not supported - results are undefined."));
|
Chris@16
|
1622 }
|
Chris@16
|
1623 return mpz_sizeinbase(val.data(), 2) - 1;
|
Chris@16
|
1624 }
|
Chris@16
|
1625
|
Chris@16
|
1626 inline bool eval_bit_test(const gmp_int& val, unsigned index)
|
Chris@16
|
1627 {
|
Chris@16
|
1628 return mpz_tstbit(val.data(), index) ? true : false;
|
Chris@16
|
1629 }
|
Chris@16
|
1630
|
Chris@16
|
1631 inline void eval_bit_set(gmp_int& val, unsigned index)
|
Chris@16
|
1632 {
|
Chris@16
|
1633 mpz_setbit(val.data(), index);
|
Chris@16
|
1634 }
|
Chris@16
|
1635
|
Chris@16
|
1636 inline void eval_bit_unset(gmp_int& val, unsigned index)
|
Chris@16
|
1637 {
|
Chris@16
|
1638 mpz_clrbit(val.data(), index);
|
Chris@16
|
1639 }
|
Chris@16
|
1640
|
Chris@16
|
1641 inline void eval_bit_flip(gmp_int& val, unsigned index)
|
Chris@16
|
1642 {
|
Chris@16
|
1643 mpz_combit(val.data(), index);
|
Chris@16
|
1644 }
|
Chris@16
|
1645
|
Chris@16
|
1646 inline void eval_qr(const gmp_int& x, const gmp_int& y,
|
Chris@16
|
1647 gmp_int& q, gmp_int& r)
|
Chris@16
|
1648 {
|
Chris@16
|
1649 mpz_tdiv_qr(q.data(), r.data(), x.data(), y.data());
|
Chris@16
|
1650 }
|
Chris@16
|
1651
|
Chris@16
|
1652 template <class Integer>
|
Chris@16
|
1653 inline typename enable_if<is_unsigned<Integer>, Integer>::type eval_integer_modulus(const gmp_int& x, Integer val)
|
Chris@16
|
1654 {
|
Chris@16
|
1655 if((sizeof(Integer) <= sizeof(long)) || (val <= (std::numeric_limits<unsigned long>::max)()))
|
Chris@16
|
1656 {
|
Chris@16
|
1657 return mpz_tdiv_ui(x.data(), val);
|
Chris@16
|
1658 }
|
Chris@16
|
1659 else
|
Chris@16
|
1660 {
|
Chris@16
|
1661 return default_ops::eval_integer_modulus(x, val);
|
Chris@16
|
1662 }
|
Chris@16
|
1663 }
|
Chris@16
|
1664 template <class Integer>
|
Chris@16
|
1665 inline typename enable_if<is_signed<Integer>, Integer>::type eval_integer_modulus(const gmp_int& x, Integer val)
|
Chris@16
|
1666 {
|
Chris@16
|
1667 typedef typename make_unsigned<Integer>::type unsigned_type;
|
Chris@16
|
1668 return eval_integer_modulus(x, static_cast<unsigned_type>(std::abs(val)));
|
Chris@16
|
1669 }
|
Chris@16
|
1670 inline void eval_powm(gmp_int& result, const gmp_int& base, const gmp_int& p, const gmp_int& m)
|
Chris@16
|
1671 {
|
Chris@16
|
1672 if(eval_get_sign(p) < 0)
|
Chris@16
|
1673 {
|
Chris@16
|
1674 BOOST_THROW_EXCEPTION(std::runtime_error("powm requires a positive exponent."));
|
Chris@16
|
1675 }
|
Chris@16
|
1676 mpz_powm(result.data(), base.data(), p.data(), m.data());
|
Chris@16
|
1677 }
|
Chris@16
|
1678
|
Chris@16
|
1679 template <class Integer>
|
Chris@16
|
1680 inline typename enable_if<
|
Chris@16
|
1681 mpl::and_<
|
Chris@16
|
1682 is_unsigned<Integer>,
|
Chris@16
|
1683 mpl::bool_<sizeof(Integer) <= sizeof(unsigned long)>
|
Chris@16
|
1684 >
|
Chris@16
|
1685 >::type eval_powm(gmp_int& result, const gmp_int& base, Integer p, const gmp_int& m)
|
Chris@16
|
1686 {
|
Chris@16
|
1687 mpz_powm_ui(result.data(), base.data(), p, m.data());
|
Chris@16
|
1688 }
|
Chris@16
|
1689 template <class Integer>
|
Chris@16
|
1690 inline typename enable_if<
|
Chris@16
|
1691 mpl::and_<
|
Chris@16
|
1692 is_signed<Integer>,
|
Chris@16
|
1693 mpl::bool_<sizeof(Integer) <= sizeof(unsigned long)>
|
Chris@16
|
1694 >
|
Chris@16
|
1695 >::type eval_powm(gmp_int& result, const gmp_int& base, Integer p, const gmp_int& m)
|
Chris@16
|
1696 {
|
Chris@16
|
1697 if(p < 0)
|
Chris@16
|
1698 {
|
Chris@16
|
1699 BOOST_THROW_EXCEPTION(std::runtime_error("powm requires a positive exponent."));
|
Chris@16
|
1700 }
|
Chris@16
|
1701 mpz_powm_ui(result.data(), base.data(), p, m.data());
|
Chris@16
|
1702 }
|
Chris@16
|
1703
|
Chris@16
|
1704 struct gmp_rational;
|
Chris@16
|
1705 void eval_add(gmp_rational& t, const gmp_rational& o);
|
Chris@16
|
1706
|
Chris@16
|
1707 struct gmp_rational
|
Chris@16
|
1708 {
|
Chris@16
|
1709 typedef mpl::list<long, long long> signed_types;
|
Chris@16
|
1710 typedef mpl::list<unsigned long, unsigned long long> unsigned_types;
|
Chris@16
|
1711 typedef mpl::list<double, long double> float_types;
|
Chris@16
|
1712
|
Chris@16
|
1713 gmp_rational()
|
Chris@16
|
1714 {
|
Chris@16
|
1715 mpq_init(this->m_data);
|
Chris@16
|
1716 }
|
Chris@16
|
1717 gmp_rational(const gmp_rational& o)
|
Chris@16
|
1718 {
|
Chris@16
|
1719 mpq_init(m_data);
|
Chris@16
|
1720 if(o.m_data[0]._mp_num._mp_d)
|
Chris@16
|
1721 mpq_set(m_data, o.m_data);
|
Chris@16
|
1722 }
|
Chris@16
|
1723 gmp_rational(const gmp_int& o)
|
Chris@16
|
1724 {
|
Chris@16
|
1725 mpq_init(m_data);
|
Chris@16
|
1726 mpq_set_z(m_data, o.data());
|
Chris@16
|
1727 }
|
Chris@16
|
1728 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
|
Chris@16
|
1729 gmp_rational(gmp_rational&& o) BOOST_NOEXCEPT
|
Chris@16
|
1730 {
|
Chris@101
|
1731 m_data[0] = o.m_data[0];
|
Chris@16
|
1732 o.m_data[0]._mp_num._mp_d = 0;
|
Chris@16
|
1733 o.m_data[0]._mp_den._mp_d = 0;
|
Chris@16
|
1734 }
|
Chris@16
|
1735 #endif
|
Chris@16
|
1736 gmp_rational(const mpq_t o)
|
Chris@16
|
1737 {
|
Chris@16
|
1738 mpq_init(m_data);
|
Chris@16
|
1739 mpq_set(m_data, o);
|
Chris@16
|
1740 }
|
Chris@16
|
1741 gmp_rational(const mpz_t o)
|
Chris@16
|
1742 {
|
Chris@16
|
1743 mpq_init(m_data);
|
Chris@16
|
1744 mpq_set_z(m_data, o);
|
Chris@16
|
1745 }
|
Chris@16
|
1746 gmp_rational& operator = (const gmp_rational& o)
|
Chris@16
|
1747 {
|
Chris@16
|
1748 if(m_data[0]._mp_den._mp_d == 0)
|
Chris@16
|
1749 mpq_init(m_data);
|
Chris@16
|
1750 mpq_set(m_data, o.m_data);
|
Chris@16
|
1751 return *this;
|
Chris@16
|
1752 }
|
Chris@16
|
1753 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
|
Chris@16
|
1754 gmp_rational& operator = (gmp_rational&& o) BOOST_NOEXCEPT
|
Chris@16
|
1755 {
|
Chris@16
|
1756 mpq_swap(m_data, o.m_data);
|
Chris@16
|
1757 return *this;
|
Chris@16
|
1758 }
|
Chris@16
|
1759 #endif
|
Chris@16
|
1760 gmp_rational& operator = (unsigned long long i)
|
Chris@16
|
1761 {
|
Chris@16
|
1762 if(m_data[0]._mp_den._mp_d == 0)
|
Chris@16
|
1763 mpq_init(m_data);
|
Chris@16
|
1764 unsigned long long mask = ((1uLL << std::numeric_limits<unsigned>::digits) - 1);
|
Chris@16
|
1765 unsigned shift = 0;
|
Chris@16
|
1766 mpq_t t;
|
Chris@16
|
1767 mpq_set_ui(m_data, 0, 1);
|
Chris@16
|
1768 mpq_init(t);
|
Chris@16
|
1769 while(i)
|
Chris@16
|
1770 {
|
Chris@16
|
1771 mpq_set_ui(t, static_cast<unsigned>(i & mask), 1);
|
Chris@16
|
1772 if(shift)
|
Chris@16
|
1773 mpq_mul_2exp(t, t, shift);
|
Chris@16
|
1774 mpq_add(m_data, m_data, t);
|
Chris@16
|
1775 shift += std::numeric_limits<unsigned>::digits;
|
Chris@16
|
1776 i >>= std::numeric_limits<unsigned>::digits;
|
Chris@16
|
1777 }
|
Chris@16
|
1778 mpq_clear(t);
|
Chris@16
|
1779 return *this;
|
Chris@16
|
1780 }
|
Chris@16
|
1781 gmp_rational& operator = (long long i)
|
Chris@16
|
1782 {
|
Chris@16
|
1783 if(m_data[0]._mp_den._mp_d == 0)
|
Chris@16
|
1784 mpq_init(m_data);
|
Chris@16
|
1785 bool neg = i < 0;
|
Chris@101
|
1786 *this = boost::multiprecision::detail::unsigned_abs(i);
|
Chris@16
|
1787 if(neg)
|
Chris@16
|
1788 mpq_neg(m_data, m_data);
|
Chris@16
|
1789 return *this;
|
Chris@16
|
1790 }
|
Chris@16
|
1791 gmp_rational& operator = (unsigned long i)
|
Chris@16
|
1792 {
|
Chris@16
|
1793 if(m_data[0]._mp_den._mp_d == 0)
|
Chris@16
|
1794 mpq_init(m_data);
|
Chris@16
|
1795 mpq_set_ui(m_data, i, 1);
|
Chris@16
|
1796 return *this;
|
Chris@16
|
1797 }
|
Chris@16
|
1798 gmp_rational& operator = (long i)
|
Chris@16
|
1799 {
|
Chris@16
|
1800 if(m_data[0]._mp_den._mp_d == 0)
|
Chris@16
|
1801 mpq_init(m_data);
|
Chris@16
|
1802 mpq_set_si(m_data, i, 1);
|
Chris@16
|
1803 return *this;
|
Chris@16
|
1804 }
|
Chris@16
|
1805 gmp_rational& operator = (double d)
|
Chris@16
|
1806 {
|
Chris@16
|
1807 if(m_data[0]._mp_den._mp_d == 0)
|
Chris@16
|
1808 mpq_init(m_data);
|
Chris@16
|
1809 mpq_set_d(m_data, d);
|
Chris@16
|
1810 return *this;
|
Chris@16
|
1811 }
|
Chris@16
|
1812 gmp_rational& operator = (long double a)
|
Chris@16
|
1813 {
|
Chris@16
|
1814 using std::frexp;
|
Chris@16
|
1815 using std::ldexp;
|
Chris@16
|
1816 using std::floor;
|
Chris@16
|
1817 using default_ops::eval_add;
|
Chris@16
|
1818 using default_ops::eval_subtract;
|
Chris@16
|
1819
|
Chris@16
|
1820 if(m_data[0]._mp_den._mp_d == 0)
|
Chris@16
|
1821 mpq_init(m_data);
|
Chris@16
|
1822
|
Chris@16
|
1823 if (a == 0) {
|
Chris@16
|
1824 mpq_set_si(m_data, 0, 1);
|
Chris@16
|
1825 return *this;
|
Chris@16
|
1826 }
|
Chris@16
|
1827
|
Chris@16
|
1828 if (a == 1) {
|
Chris@16
|
1829 mpq_set_si(m_data, 1, 1);
|
Chris@16
|
1830 return *this;
|
Chris@16
|
1831 }
|
Chris@16
|
1832
|
Chris@16
|
1833 BOOST_ASSERT(!(boost::math::isinf)(a));
|
Chris@16
|
1834 BOOST_ASSERT(!(boost::math::isnan)(a));
|
Chris@16
|
1835
|
Chris@16
|
1836 int e;
|
Chris@16
|
1837 long double f, term;
|
Chris@16
|
1838 mpq_set_ui(m_data, 0, 1);
|
Chris@16
|
1839 mpq_set_ui(m_data, 0u, 1);
|
Chris@16
|
1840 gmp_rational t;
|
Chris@16
|
1841
|
Chris@16
|
1842 f = frexp(a, &e);
|
Chris@16
|
1843
|
Chris@16
|
1844 static const int shift = std::numeric_limits<int>::digits - 1;
|
Chris@16
|
1845
|
Chris@16
|
1846 while(f)
|
Chris@16
|
1847 {
|
Chris@16
|
1848 // extract int sized bits from f:
|
Chris@16
|
1849 f = ldexp(f, shift);
|
Chris@16
|
1850 term = floor(f);
|
Chris@16
|
1851 e -= shift;
|
Chris@16
|
1852 mpq_mul_2exp(m_data, m_data, shift);
|
Chris@16
|
1853 t = static_cast<long>(term);
|
Chris@16
|
1854 eval_add(*this, t);
|
Chris@16
|
1855 f -= term;
|
Chris@16
|
1856 }
|
Chris@16
|
1857 if(e > 0)
|
Chris@16
|
1858 mpq_mul_2exp(m_data, m_data, e);
|
Chris@16
|
1859 else if(e < 0)
|
Chris@16
|
1860 mpq_div_2exp(m_data, m_data, -e);
|
Chris@16
|
1861 return *this;
|
Chris@16
|
1862 }
|
Chris@16
|
1863 gmp_rational& operator = (const char* s)
|
Chris@16
|
1864 {
|
Chris@16
|
1865 if(m_data[0]._mp_den._mp_d == 0)
|
Chris@16
|
1866 mpq_init(m_data);
|
Chris@16
|
1867 if(0 != mpq_set_str(m_data, s, 10))
|
Chris@16
|
1868 BOOST_THROW_EXCEPTION(std::runtime_error(std::string("The string \"") + s + std::string("\"could not be interpreted as a valid rational number.")));
|
Chris@16
|
1869 return *this;
|
Chris@16
|
1870 }
|
Chris@16
|
1871 gmp_rational& operator=(const gmp_int& o)
|
Chris@16
|
1872 {
|
Chris@16
|
1873 if(m_data[0]._mp_den._mp_d == 0)
|
Chris@16
|
1874 mpq_init(m_data);
|
Chris@16
|
1875 mpq_set_z(m_data, o.data());
|
Chris@16
|
1876 return *this;
|
Chris@16
|
1877 }
|
Chris@16
|
1878 gmp_rational& operator=(const mpq_t o)
|
Chris@16
|
1879 {
|
Chris@16
|
1880 if(m_data[0]._mp_den._mp_d == 0)
|
Chris@16
|
1881 mpq_init(m_data);
|
Chris@16
|
1882 mpq_set(m_data, o);
|
Chris@16
|
1883 return *this;
|
Chris@16
|
1884 }
|
Chris@16
|
1885 gmp_rational& operator=(const mpz_t o)
|
Chris@16
|
1886 {
|
Chris@16
|
1887 if(m_data[0]._mp_den._mp_d == 0)
|
Chris@16
|
1888 mpq_init(m_data);
|
Chris@16
|
1889 mpq_set_z(m_data, o);
|
Chris@16
|
1890 return *this;
|
Chris@16
|
1891 }
|
Chris@16
|
1892 void swap(gmp_rational& o)
|
Chris@16
|
1893 {
|
Chris@16
|
1894 mpq_swap(m_data, o.m_data);
|
Chris@16
|
1895 }
|
Chris@16
|
1896 std::string str(std::streamsize /*digits*/, std::ios_base::fmtflags /*f*/)const
|
Chris@16
|
1897 {
|
Chris@16
|
1898 BOOST_ASSERT(m_data[0]._mp_num._mp_d);
|
Chris@16
|
1899 // TODO make a better job of this including handling of f!!
|
Chris@16
|
1900 void *(*alloc_func_ptr) (size_t);
|
Chris@16
|
1901 void *(*realloc_func_ptr) (void *, size_t, size_t);
|
Chris@16
|
1902 void (*free_func_ptr) (void *, size_t);
|
Chris@16
|
1903 const char* ps = mpq_get_str (0, 10, m_data);
|
Chris@16
|
1904 std::string s = ps;
|
Chris@16
|
1905 mp_get_memory_functions(&alloc_func_ptr, &realloc_func_ptr, &free_func_ptr);
|
Chris@16
|
1906 (*free_func_ptr)((void*)ps, std::strlen(ps) + 1);
|
Chris@16
|
1907 return s;
|
Chris@16
|
1908 }
|
Chris@16
|
1909 ~gmp_rational()
|
Chris@16
|
1910 {
|
Chris@16
|
1911 if(m_data[0]._mp_num._mp_d || m_data[0]._mp_den._mp_d)
|
Chris@16
|
1912 mpq_clear(m_data);
|
Chris@16
|
1913 }
|
Chris@16
|
1914 void negate()
|
Chris@16
|
1915 {
|
Chris@16
|
1916 BOOST_ASSERT(m_data[0]._mp_num._mp_d);
|
Chris@16
|
1917 mpq_neg(m_data, m_data);
|
Chris@16
|
1918 }
|
Chris@16
|
1919 int compare(const gmp_rational& o)const
|
Chris@16
|
1920 {
|
Chris@16
|
1921 BOOST_ASSERT(m_data[0]._mp_num._mp_d && o.m_data[0]._mp_num._mp_d);
|
Chris@16
|
1922 return mpq_cmp(m_data, o.m_data);
|
Chris@16
|
1923 }
|
Chris@16
|
1924 template <class V>
|
Chris@16
|
1925 int compare(V v)const
|
Chris@16
|
1926 {
|
Chris@16
|
1927 gmp_rational d;
|
Chris@16
|
1928 d = v;
|
Chris@16
|
1929 return compare(d);
|
Chris@16
|
1930 }
|
Chris@16
|
1931 int compare(unsigned long v)const
|
Chris@16
|
1932 {
|
Chris@16
|
1933 BOOST_ASSERT(m_data[0]._mp_num._mp_d);
|
Chris@16
|
1934 return mpq_cmp_ui(m_data, v, 1);
|
Chris@16
|
1935 }
|
Chris@16
|
1936 int compare(long v)const
|
Chris@16
|
1937 {
|
Chris@16
|
1938 BOOST_ASSERT(m_data[0]._mp_num._mp_d);
|
Chris@16
|
1939 return mpq_cmp_si(m_data, v, 1);
|
Chris@16
|
1940 }
|
Chris@16
|
1941 mpq_t& data()
|
Chris@16
|
1942 {
|
Chris@16
|
1943 BOOST_ASSERT(m_data[0]._mp_num._mp_d);
|
Chris@16
|
1944 return m_data;
|
Chris@16
|
1945 }
|
Chris@16
|
1946 const mpq_t& data()const
|
Chris@16
|
1947 {
|
Chris@16
|
1948 BOOST_ASSERT(m_data[0]._mp_num._mp_d);
|
Chris@16
|
1949 return m_data;
|
Chris@16
|
1950 }
|
Chris@16
|
1951 protected:
|
Chris@16
|
1952 mpq_t m_data;
|
Chris@16
|
1953 };
|
Chris@16
|
1954
|
Chris@16
|
1955 inline bool eval_is_zero(const gmp_rational& val)
|
Chris@16
|
1956 {
|
Chris@16
|
1957 return mpq_sgn(val.data()) == 0;
|
Chris@16
|
1958 }
|
Chris@16
|
1959 template <class T>
|
Chris@16
|
1960 inline bool eval_eq(gmp_rational& a, const T& b)
|
Chris@16
|
1961 {
|
Chris@16
|
1962 return a.compare(b) == 0;
|
Chris@16
|
1963 }
|
Chris@16
|
1964 template <class T>
|
Chris@16
|
1965 inline bool eval_lt(gmp_rational& a, const T& b)
|
Chris@16
|
1966 {
|
Chris@16
|
1967 return a.compare(b) < 0;
|
Chris@16
|
1968 }
|
Chris@16
|
1969 template <class T>
|
Chris@16
|
1970 inline bool eval_gt(gmp_rational& a, const T& b)
|
Chris@16
|
1971 {
|
Chris@16
|
1972 return a.compare(b) > 0;
|
Chris@16
|
1973 }
|
Chris@16
|
1974
|
Chris@16
|
1975 inline void eval_add(gmp_rational& t, const gmp_rational& o)
|
Chris@16
|
1976 {
|
Chris@16
|
1977 mpq_add(t.data(), t.data(), o.data());
|
Chris@16
|
1978 }
|
Chris@16
|
1979 inline void eval_subtract(gmp_rational& t, const gmp_rational& o)
|
Chris@16
|
1980 {
|
Chris@16
|
1981 mpq_sub(t.data(), t.data(), o.data());
|
Chris@16
|
1982 }
|
Chris@16
|
1983 inline void eval_multiply(gmp_rational& t, const gmp_rational& o)
|
Chris@16
|
1984 {
|
Chris@16
|
1985 mpq_mul(t.data(), t.data(), o.data());
|
Chris@16
|
1986 }
|
Chris@16
|
1987 inline void eval_divide(gmp_rational& t, const gmp_rational& o)
|
Chris@16
|
1988 {
|
Chris@16
|
1989 if(eval_is_zero(o))
|
Chris@16
|
1990 BOOST_THROW_EXCEPTION(std::overflow_error("Division by zero."));
|
Chris@16
|
1991 mpq_div(t.data(), t.data(), o.data());
|
Chris@16
|
1992 }
|
Chris@16
|
1993 inline void eval_add(gmp_rational& t, const gmp_rational& p, const gmp_rational& o)
|
Chris@16
|
1994 {
|
Chris@16
|
1995 mpq_add(t.data(), p.data(), o.data());
|
Chris@16
|
1996 }
|
Chris@16
|
1997 inline void eval_subtract(gmp_rational& t, const gmp_rational& p, const gmp_rational& o)
|
Chris@16
|
1998 {
|
Chris@16
|
1999 mpq_sub(t.data(), p.data(), o.data());
|
Chris@16
|
2000 }
|
Chris@16
|
2001 inline void eval_multiply(gmp_rational& t, const gmp_rational& p, const gmp_rational& o)
|
Chris@16
|
2002 {
|
Chris@16
|
2003 mpq_mul(t.data(), p.data(), o.data());
|
Chris@16
|
2004 }
|
Chris@16
|
2005 inline void eval_divide(gmp_rational& t, const gmp_rational& p, const gmp_rational& o)
|
Chris@16
|
2006 {
|
Chris@16
|
2007 if(eval_is_zero(o))
|
Chris@16
|
2008 BOOST_THROW_EXCEPTION(std::overflow_error("Division by zero."));
|
Chris@16
|
2009 mpq_div(t.data(), p.data(), o.data());
|
Chris@16
|
2010 }
|
Chris@16
|
2011
|
Chris@16
|
2012 inline int eval_get_sign(const gmp_rational& val)
|
Chris@16
|
2013 {
|
Chris@16
|
2014 return mpq_sgn(val.data());
|
Chris@16
|
2015 }
|
Chris@16
|
2016 inline void eval_convert_to(double* result, const gmp_rational& val)
|
Chris@16
|
2017 {
|
Chris@101
|
2018 //
|
Chris@101
|
2019 // This does not round correctly:
|
Chris@101
|
2020 //
|
Chris@101
|
2021 //*result = mpq_get_d(val.data());
|
Chris@101
|
2022 //
|
Chris@101
|
2023 // This does:
|
Chris@101
|
2024 //
|
Chris@101
|
2025 boost::multiprecision::detail::generic_convert_rational_to_float(*result, val);
|
Chris@16
|
2026 }
|
Chris@16
|
2027
|
Chris@16
|
2028 inline void eval_convert_to(long* result, const gmp_rational& val)
|
Chris@16
|
2029 {
|
Chris@16
|
2030 double r;
|
Chris@16
|
2031 eval_convert_to(&r, val);
|
Chris@16
|
2032 *result = static_cast<long>(r);
|
Chris@16
|
2033 }
|
Chris@16
|
2034
|
Chris@16
|
2035 inline void eval_convert_to(unsigned long* result, const gmp_rational& val)
|
Chris@16
|
2036 {
|
Chris@16
|
2037 double r;
|
Chris@16
|
2038 eval_convert_to(&r, val);
|
Chris@16
|
2039 *result = static_cast<long>(r);
|
Chris@16
|
2040 }
|
Chris@16
|
2041
|
Chris@16
|
2042 inline void eval_abs(gmp_rational& result, const gmp_rational& val)
|
Chris@16
|
2043 {
|
Chris@16
|
2044 mpq_abs(result.data(), val.data());
|
Chris@16
|
2045 }
|
Chris@16
|
2046
|
Chris@16
|
2047 inline void assign_components(gmp_rational& result, unsigned long v1, unsigned long v2)
|
Chris@16
|
2048 {
|
Chris@16
|
2049 mpq_set_ui(result.data(), v1, v2);
|
Chris@16
|
2050 mpq_canonicalize(result.data());
|
Chris@16
|
2051 }
|
Chris@16
|
2052 inline void assign_components(gmp_rational& result, long v1, long v2)
|
Chris@16
|
2053 {
|
Chris@16
|
2054 mpq_set_si(result.data(), v1, v2);
|
Chris@16
|
2055 mpq_canonicalize(result.data());
|
Chris@16
|
2056 }
|
Chris@16
|
2057 inline void assign_components(gmp_rational& result, gmp_int const& v1, gmp_int const& v2)
|
Chris@16
|
2058 {
|
Chris@16
|
2059 mpz_set(mpq_numref(result.data()), v1.data());
|
Chris@16
|
2060 mpz_set(mpq_denref(result.data()), v2.data());
|
Chris@16
|
2061 mpq_canonicalize(result.data());
|
Chris@16
|
2062 }
|
Chris@16
|
2063
|
Chris@16
|
2064 //
|
Chris@16
|
2065 // Some member functions that are dependent upon previous code go here:
|
Chris@16
|
2066 //
|
Chris@16
|
2067 template <unsigned Digits10>
|
Chris@16
|
2068 template <unsigned D>
|
Chris@16
|
2069 inline gmp_float<Digits10>::gmp_float(const gmp_float<D>& o, typename enable_if_c<D <= Digits10>::type*)
|
Chris@16
|
2070 {
|
Chris@16
|
2071 mpf_init2(this->m_data, multiprecision::detail::digits10_2_2(Digits10 ? Digits10 : this->get_default_precision()));
|
Chris@16
|
2072 mpf_set(this->m_data, o.data());
|
Chris@16
|
2073 }
|
Chris@16
|
2074 template <unsigned Digits10>
|
Chris@16
|
2075 template <unsigned D>
|
Chris@16
|
2076 inline gmp_float<Digits10>::gmp_float(const gmp_float<D>& o, typename disable_if_c<D <= Digits10>::type*)
|
Chris@16
|
2077 {
|
Chris@16
|
2078 mpf_init2(this->m_data, multiprecision::detail::digits10_2_2(Digits10 ? Digits10 : this->get_default_precision()));
|
Chris@16
|
2079 mpf_set(this->m_data, o.data());
|
Chris@16
|
2080 }
|
Chris@16
|
2081 template <unsigned Digits10>
|
Chris@16
|
2082 inline gmp_float<Digits10>::gmp_float(const gmp_int& o)
|
Chris@16
|
2083 {
|
Chris@16
|
2084 mpf_init2(this->m_data, multiprecision::detail::digits10_2_2(Digits10 ? Digits10 : this->get_default_precision()));
|
Chris@16
|
2085 mpf_set_z(this->data(), o.data());
|
Chris@16
|
2086 }
|
Chris@16
|
2087 template <unsigned Digits10>
|
Chris@16
|
2088 inline gmp_float<Digits10>::gmp_float(const gmp_rational& o)
|
Chris@16
|
2089 {
|
Chris@16
|
2090 mpf_init2(this->m_data, multiprecision::detail::digits10_2_2(Digits10 ? Digits10 : this->get_default_precision()));
|
Chris@16
|
2091 mpf_set_q(this->data(), o.data());
|
Chris@16
|
2092 }
|
Chris@16
|
2093 template <unsigned Digits10>
|
Chris@16
|
2094 template <unsigned D>
|
Chris@16
|
2095 inline gmp_float<Digits10>& gmp_float<Digits10>::operator=(const gmp_float<D>& o)
|
Chris@16
|
2096 {
|
Chris@16
|
2097 if(this->m_data[0]._mp_d == 0)
|
Chris@16
|
2098 mpf_init2(this->m_data, multiprecision::detail::digits10_2_2(Digits10 ? Digits10 : this->get_default_precision()));
|
Chris@16
|
2099 mpf_set(this->m_data, o.data());
|
Chris@16
|
2100 return *this;
|
Chris@16
|
2101 }
|
Chris@16
|
2102 template <unsigned Digits10>
|
Chris@16
|
2103 inline gmp_float<Digits10>& gmp_float<Digits10>::operator=(const gmp_int& o)
|
Chris@16
|
2104 {
|
Chris@16
|
2105 if(this->m_data[0]._mp_d == 0)
|
Chris@16
|
2106 mpf_init2(this->m_data, multiprecision::detail::digits10_2_2(Digits10 ? Digits10 : this->get_default_precision()));
|
Chris@16
|
2107 mpf_set_z(this->data(), o.data());
|
Chris@16
|
2108 return *this;
|
Chris@16
|
2109 }
|
Chris@16
|
2110 template <unsigned Digits10>
|
Chris@16
|
2111 inline gmp_float<Digits10>& gmp_float<Digits10>::operator=(const gmp_rational& o)
|
Chris@16
|
2112 {
|
Chris@16
|
2113 if(this->m_data[0]._mp_d == 0)
|
Chris@16
|
2114 mpf_init2(this->m_data, multiprecision::detail::digits10_2_2(Digits10 ? Digits10 : this->get_default_precision()));
|
Chris@16
|
2115 mpf_set_q(this->data(), o.data());
|
Chris@16
|
2116 return *this;
|
Chris@16
|
2117 }
|
Chris@16
|
2118 inline gmp_float<0>::gmp_float(const gmp_int& o)
|
Chris@16
|
2119 {
|
Chris@16
|
2120 mpf_init2(this->m_data, multiprecision::detail::digits10_2_2(get_default_precision()));
|
Chris@16
|
2121 mpf_set_z(this->data(), o.data());
|
Chris@16
|
2122 }
|
Chris@16
|
2123 inline gmp_float<0>::gmp_float(const gmp_rational& o)
|
Chris@16
|
2124 {
|
Chris@16
|
2125 mpf_init2(this->m_data, multiprecision::detail::digits10_2_2(get_default_precision()));
|
Chris@16
|
2126 mpf_set_q(this->data(), o.data());
|
Chris@16
|
2127 }
|
Chris@16
|
2128 inline gmp_float<0>& gmp_float<0>::operator=(const gmp_int& o)
|
Chris@16
|
2129 {
|
Chris@16
|
2130 if(this->m_data[0]._mp_d == 0)
|
Chris@16
|
2131 mpf_init2(this->m_data, multiprecision::detail::digits10_2_2(this->get_default_precision()));
|
Chris@16
|
2132 mpf_set_z(this->data(), o.data());
|
Chris@16
|
2133 return *this;
|
Chris@16
|
2134 }
|
Chris@16
|
2135 inline gmp_float<0>& gmp_float<0>::operator=(const gmp_rational& o)
|
Chris@16
|
2136 {
|
Chris@16
|
2137 if(this->m_data[0]._mp_d == 0)
|
Chris@16
|
2138 mpf_init2(this->m_data, multiprecision::detail::digits10_2_2(this->get_default_precision()));
|
Chris@16
|
2139 mpf_set_q(this->data(), o.data());
|
Chris@16
|
2140 return *this;
|
Chris@16
|
2141 }
|
Chris@16
|
2142 inline gmp_int::gmp_int(const gmp_rational& o)
|
Chris@16
|
2143 {
|
Chris@16
|
2144 mpz_init(this->m_data);
|
Chris@16
|
2145 mpz_set_q(this->m_data, o.data());
|
Chris@16
|
2146 }
|
Chris@16
|
2147 inline gmp_int& gmp_int::operator=(const gmp_rational& o)
|
Chris@16
|
2148 {
|
Chris@16
|
2149 if(this->m_data[0]._mp_d == 0)
|
Chris@16
|
2150 mpz_init(this->m_data);
|
Chris@16
|
2151 mpz_set_q(this->m_data, o.data());
|
Chris@16
|
2152 return *this;
|
Chris@16
|
2153 }
|
Chris@16
|
2154
|
Chris@16
|
2155 } //namespace backends
|
Chris@16
|
2156
|
Chris@16
|
2157 using boost::multiprecision::backends::gmp_int;
|
Chris@16
|
2158 using boost::multiprecision::backends::gmp_rational;
|
Chris@16
|
2159 using boost::multiprecision::backends::gmp_float;
|
Chris@16
|
2160
|
Chris@16
|
2161 template <>
|
Chris@16
|
2162 struct component_type<number<gmp_rational> >
|
Chris@16
|
2163 {
|
Chris@16
|
2164 typedef number<gmp_int> type;
|
Chris@16
|
2165 };
|
Chris@16
|
2166
|
Chris@16
|
2167 template <expression_template_option ET>
|
Chris@16
|
2168 inline number<gmp_int, ET> numerator(const number<gmp_rational, ET>& val)
|
Chris@16
|
2169 {
|
Chris@16
|
2170 number<gmp_int, ET> result;
|
Chris@16
|
2171 mpz_set(result.backend().data(), (mpq_numref(val.backend().data())));
|
Chris@16
|
2172 return result;
|
Chris@16
|
2173 }
|
Chris@16
|
2174 template <expression_template_option ET>
|
Chris@16
|
2175 inline number<gmp_int, ET> denominator(const number<gmp_rational, ET>& val)
|
Chris@16
|
2176 {
|
Chris@16
|
2177 number<gmp_int, ET> result;
|
Chris@16
|
2178 mpz_set(result.backend().data(), (mpq_denref(val.backend().data())));
|
Chris@16
|
2179 return result;
|
Chris@16
|
2180 }
|
Chris@16
|
2181
|
Chris@16
|
2182 #ifdef BOOST_NO_SFINAE_EXPR
|
Chris@16
|
2183
|
Chris@16
|
2184 namespace detail{
|
Chris@16
|
2185
|
Chris@16
|
2186 template<>
|
Chris@16
|
2187 struct is_explicitly_convertible<canonical<mpf_t, gmp_int>::type, gmp_int> : public mpl::true_ {};
|
Chris@16
|
2188 template<>
|
Chris@16
|
2189 struct is_explicitly_convertible<canonical<mpq_t, gmp_int>::type, gmp_int> : public mpl::true_ {};
|
Chris@16
|
2190 template<unsigned Digits10>
|
Chris@16
|
2191 struct is_explicitly_convertible<gmp_float<Digits10>, gmp_int> : public mpl::true_ {};
|
Chris@16
|
2192 template<>
|
Chris@16
|
2193 struct is_explicitly_convertible<gmp_rational, gmp_int> : public mpl::true_ {};
|
Chris@16
|
2194 template<unsigned D1, unsigned D2>
|
Chris@16
|
2195 struct is_explicitly_convertible<gmp_float<D1>, gmp_float<D2> > : public mpl::true_ {};
|
Chris@16
|
2196
|
Chris@16
|
2197 }
|
Chris@16
|
2198
|
Chris@16
|
2199 #endif
|
Chris@16
|
2200
|
Chris@16
|
2201 template<>
|
Chris@16
|
2202 struct number_category<detail::canonical<mpz_t, gmp_int>::type> : public mpl::int_<number_kind_integer>{};
|
Chris@16
|
2203 template<>
|
Chris@16
|
2204 struct number_category<detail::canonical<mpq_t, gmp_rational>::type> : public mpl::int_<number_kind_rational>{};
|
Chris@16
|
2205 template<>
|
Chris@16
|
2206 struct number_category<detail::canonical<mpf_t, gmp_float<0> >::type> : public mpl::int_<number_kind_floating_point>{};
|
Chris@16
|
2207
|
Chris@16
|
2208
|
Chris@16
|
2209 typedef number<gmp_float<50> > mpf_float_50;
|
Chris@16
|
2210 typedef number<gmp_float<100> > mpf_float_100;
|
Chris@16
|
2211 typedef number<gmp_float<500> > mpf_float_500;
|
Chris@16
|
2212 typedef number<gmp_float<1000> > mpf_float_1000;
|
Chris@16
|
2213 typedef number<gmp_float<0> > mpf_float;
|
Chris@16
|
2214 typedef number<gmp_int > mpz_int;
|
Chris@16
|
2215 typedef number<gmp_rational > mpq_rational;
|
Chris@16
|
2216
|
Chris@16
|
2217 }} // namespaces
|
Chris@16
|
2218
|
Chris@16
|
2219 namespace std{
|
Chris@16
|
2220
|
Chris@16
|
2221 //
|
Chris@16
|
2222 // numeric_limits [partial] specializations for the types declared in this header:
|
Chris@16
|
2223 //
|
Chris@16
|
2224 template<unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
|
Chris@16
|
2225 class numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<Digits10>, ExpressionTemplates> >
|
Chris@16
|
2226 {
|
Chris@16
|
2227 typedef boost::multiprecision::number<boost::multiprecision::gmp_float<Digits10>, ExpressionTemplates> number_type;
|
Chris@16
|
2228 public:
|
Chris@16
|
2229 BOOST_STATIC_CONSTEXPR bool is_specialized = true;
|
Chris@16
|
2230 //
|
Chris@16
|
2231 // min and max values chosen so as to not cause segfaults when calling
|
Chris@16
|
2232 // mpf_get_str on 64-bit Linux builds. Possibly we could use larger
|
Chris@16
|
2233 // exponent values elsewhere.
|
Chris@16
|
2234 //
|
Chris@16
|
2235 static number_type (min)()
|
Chris@16
|
2236 {
|
Chris@16
|
2237 initializer.do_nothing();
|
Chris@16
|
2238 static std::pair<bool, number_type> value;
|
Chris@16
|
2239 if(!value.first)
|
Chris@16
|
2240 {
|
Chris@16
|
2241 value.first = true;
|
Chris@16
|
2242 value.second = 1;
|
Chris@16
|
2243 mpf_div_2exp(value.second.backend().data(), value.second.backend().data(), (std::numeric_limits<mp_exp_t>::max)() / 64 + 1);
|
Chris@16
|
2244 }
|
Chris@16
|
2245 return value.second;
|
Chris@16
|
2246 }
|
Chris@16
|
2247 static number_type (max)()
|
Chris@16
|
2248 {
|
Chris@16
|
2249 initializer.do_nothing();
|
Chris@16
|
2250 static std::pair<bool, number_type> value;
|
Chris@16
|
2251 if(!value.first)
|
Chris@16
|
2252 {
|
Chris@16
|
2253 value.first = true;
|
Chris@16
|
2254 value.second = 1;
|
Chris@16
|
2255 mpf_mul_2exp(value.second.backend().data(), value.second.backend().data(), (std::numeric_limits<mp_exp_t>::max)() / 64 + 1);
|
Chris@16
|
2256 }
|
Chris@16
|
2257 return value.second;
|
Chris@16
|
2258 }
|
Chris@16
|
2259 BOOST_STATIC_CONSTEXPR number_type lowest()
|
Chris@16
|
2260 {
|
Chris@16
|
2261 return -(max)();
|
Chris@16
|
2262 }
|
Chris@16
|
2263 BOOST_STATIC_CONSTEXPR int digits = static_cast<int>((Digits10 * 1000L) / 301L + ((Digits10 * 1000L) % 301L ? 2 : 1));
|
Chris@16
|
2264 BOOST_STATIC_CONSTEXPR int digits10 = Digits10;
|
Chris@16
|
2265 // Have to allow for a possible extra limb inside the gmp data structure:
|
Chris@16
|
2266 BOOST_STATIC_CONSTEXPR int max_digits10 = Digits10 + 2 + ((GMP_LIMB_BITS * 301L) / 1000L);
|
Chris@16
|
2267 BOOST_STATIC_CONSTEXPR bool is_signed = true;
|
Chris@16
|
2268 BOOST_STATIC_CONSTEXPR bool is_integer = false;
|
Chris@16
|
2269 BOOST_STATIC_CONSTEXPR bool is_exact = false;
|
Chris@16
|
2270 BOOST_STATIC_CONSTEXPR int radix = 2;
|
Chris@16
|
2271 static number_type epsilon()
|
Chris@16
|
2272 {
|
Chris@16
|
2273 initializer.do_nothing();
|
Chris@16
|
2274 static std::pair<bool, number_type> value;
|
Chris@16
|
2275 if(!value.first)
|
Chris@16
|
2276 {
|
Chris@16
|
2277 value.first = true;
|
Chris@16
|
2278 value.second = 1;
|
Chris@16
|
2279 mpf_div_2exp(value.second.backend().data(), value.second.backend().data(), std::numeric_limits<number_type>::digits - 1);
|
Chris@16
|
2280 }
|
Chris@16
|
2281 return value.second;
|
Chris@16
|
2282 }
|
Chris@16
|
2283 // What value should this be????
|
Chris@16
|
2284 static number_type round_error()
|
Chris@16
|
2285 {
|
Chris@16
|
2286 // returns epsilon/2
|
Chris@16
|
2287 initializer.do_nothing();
|
Chris@16
|
2288 static std::pair<bool, number_type> value;
|
Chris@16
|
2289 if(!value.first)
|
Chris@16
|
2290 {
|
Chris@16
|
2291 value.first = true;
|
Chris@16
|
2292 value.second = 1;
|
Chris@16
|
2293 }
|
Chris@16
|
2294 return value.second;
|
Chris@16
|
2295 }
|
Chris@16
|
2296 BOOST_STATIC_CONSTEXPR long min_exponent = LONG_MIN;
|
Chris@16
|
2297 BOOST_STATIC_CONSTEXPR long min_exponent10 = (LONG_MIN / 1000) * 301L;
|
Chris@16
|
2298 BOOST_STATIC_CONSTEXPR long max_exponent = LONG_MAX;
|
Chris@16
|
2299 BOOST_STATIC_CONSTEXPR long max_exponent10 = (LONG_MAX / 1000) * 301L;
|
Chris@16
|
2300 BOOST_STATIC_CONSTEXPR bool has_infinity = false;
|
Chris@16
|
2301 BOOST_STATIC_CONSTEXPR bool has_quiet_NaN = false;
|
Chris@16
|
2302 BOOST_STATIC_CONSTEXPR bool has_signaling_NaN = false;
|
Chris@16
|
2303 BOOST_STATIC_CONSTEXPR float_denorm_style has_denorm = denorm_absent;
|
Chris@16
|
2304 BOOST_STATIC_CONSTEXPR bool has_denorm_loss = false;
|
Chris@16
|
2305 BOOST_STATIC_CONSTEXPR number_type infinity() { return number_type(); }
|
Chris@16
|
2306 BOOST_STATIC_CONSTEXPR number_type quiet_NaN() { return number_type(); }
|
Chris@16
|
2307 BOOST_STATIC_CONSTEXPR number_type signaling_NaN() { return number_type(); }
|
Chris@16
|
2308 BOOST_STATIC_CONSTEXPR number_type denorm_min() { return number_type(); }
|
Chris@16
|
2309 BOOST_STATIC_CONSTEXPR bool is_iec559 = false;
|
Chris@16
|
2310 BOOST_STATIC_CONSTEXPR bool is_bounded = true;
|
Chris@16
|
2311 BOOST_STATIC_CONSTEXPR bool is_modulo = false;
|
Chris@16
|
2312 BOOST_STATIC_CONSTEXPR bool traps = true;
|
Chris@16
|
2313 BOOST_STATIC_CONSTEXPR bool tinyness_before = false;
|
Chris@16
|
2314 BOOST_STATIC_CONSTEXPR float_round_style round_style = round_indeterminate;
|
Chris@16
|
2315
|
Chris@16
|
2316 private:
|
Chris@16
|
2317 struct data_initializer
|
Chris@16
|
2318 {
|
Chris@16
|
2319 data_initializer()
|
Chris@16
|
2320 {
|
Chris@16
|
2321 std::numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<digits10> > >::epsilon();
|
Chris@16
|
2322 std::numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<digits10> > >::round_error();
|
Chris@16
|
2323 (std::numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<digits10> > >::min)();
|
Chris@16
|
2324 (std::numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<digits10> > >::max)();
|
Chris@16
|
2325 }
|
Chris@16
|
2326 void do_nothing()const{}
|
Chris@16
|
2327 };
|
Chris@16
|
2328 static const data_initializer initializer;
|
Chris@16
|
2329 };
|
Chris@16
|
2330
|
Chris@16
|
2331 template<unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
|
Chris@16
|
2332 const typename numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<Digits10>, ExpressionTemplates> >::data_initializer numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<Digits10>, ExpressionTemplates> >::initializer;
|
Chris@16
|
2333
|
Chris@101
|
2334 #ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION
|
Chris@101
|
2335
|
Chris@101
|
2336 template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
|
Chris@101
|
2337 BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<Digits10>, ExpressionTemplates> >::digits;
|
Chris@101
|
2338 template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
|
Chris@101
|
2339 BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<Digits10>, ExpressionTemplates> >::digits10;
|
Chris@101
|
2340 template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
|
Chris@101
|
2341 BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<Digits10>, ExpressionTemplates> >::max_digits10;
|
Chris@101
|
2342 template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
|
Chris@101
|
2343 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<Digits10>, ExpressionTemplates> >::is_signed;
|
Chris@101
|
2344 template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
|
Chris@101
|
2345 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<Digits10>, ExpressionTemplates> >::is_integer;
|
Chris@101
|
2346 template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
|
Chris@101
|
2347 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<Digits10>, ExpressionTemplates> >::is_exact;
|
Chris@101
|
2348 template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
|
Chris@101
|
2349 BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<Digits10>, ExpressionTemplates> >::radix;
|
Chris@101
|
2350 template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
|
Chris@101
|
2351 BOOST_CONSTEXPR_OR_CONST long numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<Digits10>, ExpressionTemplates> >::min_exponent;
|
Chris@101
|
2352 template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
|
Chris@101
|
2353 BOOST_CONSTEXPR_OR_CONST long numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<Digits10>, ExpressionTemplates> >::min_exponent10;
|
Chris@101
|
2354 template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
|
Chris@101
|
2355 BOOST_CONSTEXPR_OR_CONST long numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<Digits10>, ExpressionTemplates> >::max_exponent;
|
Chris@101
|
2356 template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
|
Chris@101
|
2357 BOOST_CONSTEXPR_OR_CONST long numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<Digits10>, ExpressionTemplates> >::max_exponent10;
|
Chris@101
|
2358 template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
|
Chris@101
|
2359 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<Digits10>, ExpressionTemplates> >::has_infinity;
|
Chris@101
|
2360 template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
|
Chris@101
|
2361 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<Digits10>, ExpressionTemplates> >::has_quiet_NaN;
|
Chris@101
|
2362 template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
|
Chris@101
|
2363 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<Digits10>, ExpressionTemplates> >::has_signaling_NaN;
|
Chris@101
|
2364 template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
|
Chris@101
|
2365 BOOST_CONSTEXPR_OR_CONST float_denorm_style numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<Digits10>, ExpressionTemplates> >::has_denorm;
|
Chris@101
|
2366 template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
|
Chris@101
|
2367 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<Digits10>, ExpressionTemplates> >::has_denorm_loss;
|
Chris@101
|
2368 template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
|
Chris@101
|
2369 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<Digits10>, ExpressionTemplates> >::is_iec559;
|
Chris@101
|
2370 template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
|
Chris@101
|
2371 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<Digits10>, ExpressionTemplates> >::is_bounded;
|
Chris@101
|
2372 template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
|
Chris@101
|
2373 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<Digits10>, ExpressionTemplates> >::is_modulo;
|
Chris@101
|
2374 template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
|
Chris@101
|
2375 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<Digits10>, ExpressionTemplates> >::traps;
|
Chris@101
|
2376 template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
|
Chris@101
|
2377 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<Digits10>, ExpressionTemplates> >::tinyness_before;
|
Chris@101
|
2378 template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
|
Chris@101
|
2379 BOOST_CONSTEXPR_OR_CONST float_round_style numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<Digits10>, ExpressionTemplates> >::round_style;
|
Chris@101
|
2380
|
Chris@101
|
2381 #endif
|
Chris@101
|
2382
|
Chris@16
|
2383 template<boost::multiprecision::expression_template_option ExpressionTemplates>
|
Chris@16
|
2384 class numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<0>, ExpressionTemplates> >
|
Chris@16
|
2385 {
|
Chris@16
|
2386 typedef boost::multiprecision::number<boost::multiprecision::gmp_float<0>, ExpressionTemplates> number_type;
|
Chris@16
|
2387 public:
|
Chris@16
|
2388 BOOST_STATIC_CONSTEXPR bool is_specialized = false;
|
Chris@16
|
2389 static number_type (min)() { return number_type(); }
|
Chris@16
|
2390 static number_type (max)() { return number_type(); }
|
Chris@16
|
2391 static number_type lowest() { return number_type(); }
|
Chris@16
|
2392 BOOST_STATIC_CONSTEXPR int digits = 0;
|
Chris@16
|
2393 BOOST_STATIC_CONSTEXPR int digits10 = 0;
|
Chris@16
|
2394 BOOST_STATIC_CONSTEXPR int max_digits10 = 0;
|
Chris@16
|
2395 BOOST_STATIC_CONSTEXPR bool is_signed = false;
|
Chris@16
|
2396 BOOST_STATIC_CONSTEXPR bool is_integer = false;
|
Chris@16
|
2397 BOOST_STATIC_CONSTEXPR bool is_exact = false;
|
Chris@16
|
2398 BOOST_STATIC_CONSTEXPR int radix = 0;
|
Chris@16
|
2399 static number_type epsilon() { return number_type(); }
|
Chris@16
|
2400 static number_type round_error() { return number_type(); }
|
Chris@16
|
2401 BOOST_STATIC_CONSTEXPR int min_exponent = 0;
|
Chris@16
|
2402 BOOST_STATIC_CONSTEXPR int min_exponent10 = 0;
|
Chris@16
|
2403 BOOST_STATIC_CONSTEXPR int max_exponent = 0;
|
Chris@16
|
2404 BOOST_STATIC_CONSTEXPR int max_exponent10 = 0;
|
Chris@16
|
2405 BOOST_STATIC_CONSTEXPR bool has_infinity = false;
|
Chris@16
|
2406 BOOST_STATIC_CONSTEXPR bool has_quiet_NaN = false;
|
Chris@16
|
2407 BOOST_STATIC_CONSTEXPR bool has_signaling_NaN = false;
|
Chris@16
|
2408 BOOST_STATIC_CONSTEXPR float_denorm_style has_denorm = denorm_absent;
|
Chris@16
|
2409 BOOST_STATIC_CONSTEXPR bool has_denorm_loss = false;
|
Chris@16
|
2410 static number_type infinity() { return number_type(); }
|
Chris@16
|
2411 static number_type quiet_NaN() { return number_type(); }
|
Chris@16
|
2412 static number_type signaling_NaN() { return number_type(); }
|
Chris@16
|
2413 static number_type denorm_min() { return number_type(); }
|
Chris@16
|
2414 BOOST_STATIC_CONSTEXPR bool is_iec559 = false;
|
Chris@16
|
2415 BOOST_STATIC_CONSTEXPR bool is_bounded = false;
|
Chris@16
|
2416 BOOST_STATIC_CONSTEXPR bool is_modulo = false;
|
Chris@16
|
2417 BOOST_STATIC_CONSTEXPR bool traps = false;
|
Chris@16
|
2418 BOOST_STATIC_CONSTEXPR bool tinyness_before = false;
|
Chris@16
|
2419 BOOST_STATIC_CONSTEXPR float_round_style round_style = round_indeterminate;
|
Chris@16
|
2420 };
|
Chris@16
|
2421
|
Chris@16
|
2422 #ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION
|
Chris@16
|
2423
|
Chris@16
|
2424 template <boost::multiprecision::expression_template_option ExpressionTemplates>
|
Chris@16
|
2425 BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<0>, ExpressionTemplates> >::digits;
|
Chris@16
|
2426 template <boost::multiprecision::expression_template_option ExpressionTemplates>
|
Chris@16
|
2427 BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<0>, ExpressionTemplates> >::digits10;
|
Chris@16
|
2428 template <boost::multiprecision::expression_template_option ExpressionTemplates>
|
Chris@16
|
2429 BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<0>, ExpressionTemplates> >::max_digits10;
|
Chris@16
|
2430 template <boost::multiprecision::expression_template_option ExpressionTemplates>
|
Chris@16
|
2431 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<0>, ExpressionTemplates> >::is_signed;
|
Chris@16
|
2432 template <boost::multiprecision::expression_template_option ExpressionTemplates>
|
Chris@16
|
2433 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<0>, ExpressionTemplates> >::is_integer;
|
Chris@16
|
2434 template <boost::multiprecision::expression_template_option ExpressionTemplates>
|
Chris@16
|
2435 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<0>, ExpressionTemplates> >::is_exact;
|
Chris@16
|
2436 template <boost::multiprecision::expression_template_option ExpressionTemplates>
|
Chris@16
|
2437 BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<0>, ExpressionTemplates> >::radix;
|
Chris@16
|
2438 template <boost::multiprecision::expression_template_option ExpressionTemplates>
|
Chris@16
|
2439 BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<0>, ExpressionTemplates> >::min_exponent;
|
Chris@16
|
2440 template <boost::multiprecision::expression_template_option ExpressionTemplates>
|
Chris@16
|
2441 BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<0>, ExpressionTemplates> >::min_exponent10;
|
Chris@16
|
2442 template <boost::multiprecision::expression_template_option ExpressionTemplates>
|
Chris@16
|
2443 BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<0>, ExpressionTemplates> >::max_exponent;
|
Chris@16
|
2444 template <boost::multiprecision::expression_template_option ExpressionTemplates>
|
Chris@16
|
2445 BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<0>, ExpressionTemplates> >::max_exponent10;
|
Chris@16
|
2446 template <boost::multiprecision::expression_template_option ExpressionTemplates>
|
Chris@16
|
2447 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<0>, ExpressionTemplates> >::has_infinity;
|
Chris@16
|
2448 template <boost::multiprecision::expression_template_option ExpressionTemplates>
|
Chris@16
|
2449 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<0>, ExpressionTemplates> >::has_quiet_NaN;
|
Chris@16
|
2450 template <boost::multiprecision::expression_template_option ExpressionTemplates>
|
Chris@16
|
2451 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<0>, ExpressionTemplates> >::has_signaling_NaN;
|
Chris@16
|
2452 template <boost::multiprecision::expression_template_option ExpressionTemplates>
|
Chris@16
|
2453 BOOST_CONSTEXPR_OR_CONST float_denorm_style numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<0>, ExpressionTemplates> >::has_denorm;
|
Chris@16
|
2454 template <boost::multiprecision::expression_template_option ExpressionTemplates>
|
Chris@16
|
2455 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<0>, ExpressionTemplates> >::has_denorm_loss;
|
Chris@16
|
2456 template <boost::multiprecision::expression_template_option ExpressionTemplates>
|
Chris@16
|
2457 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<0>, ExpressionTemplates> >::is_iec559;
|
Chris@16
|
2458 template <boost::multiprecision::expression_template_option ExpressionTemplates>
|
Chris@16
|
2459 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<0>, ExpressionTemplates> >::is_bounded;
|
Chris@16
|
2460 template <boost::multiprecision::expression_template_option ExpressionTemplates>
|
Chris@16
|
2461 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<0>, ExpressionTemplates> >::is_modulo;
|
Chris@16
|
2462 template <boost::multiprecision::expression_template_option ExpressionTemplates>
|
Chris@16
|
2463 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<0>, ExpressionTemplates> >::traps;
|
Chris@16
|
2464 template <boost::multiprecision::expression_template_option ExpressionTemplates>
|
Chris@16
|
2465 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<0>, ExpressionTemplates> >::tinyness_before;
|
Chris@16
|
2466 template <boost::multiprecision::expression_template_option ExpressionTemplates>
|
Chris@16
|
2467 BOOST_CONSTEXPR_OR_CONST float_round_style numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<0>, ExpressionTemplates> >::round_style;
|
Chris@16
|
2468
|
Chris@16
|
2469 #endif
|
Chris@16
|
2470
|
Chris@16
|
2471 template<boost::multiprecision::expression_template_option ExpressionTemplates>
|
Chris@16
|
2472 class numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_int, ExpressionTemplates> >
|
Chris@16
|
2473 {
|
Chris@16
|
2474 typedef boost::multiprecision::number<boost::multiprecision::gmp_int, ExpressionTemplates> number_type;
|
Chris@16
|
2475 public:
|
Chris@16
|
2476 BOOST_STATIC_CONSTEXPR bool is_specialized = true;
|
Chris@16
|
2477 //
|
Chris@16
|
2478 // Largest and smallest numbers are bounded only by available memory, set
|
Chris@16
|
2479 // to zero:
|
Chris@16
|
2480 //
|
Chris@16
|
2481 static number_type (min)()
|
Chris@16
|
2482 {
|
Chris@16
|
2483 return number_type();
|
Chris@16
|
2484 }
|
Chris@16
|
2485 static number_type (max)()
|
Chris@16
|
2486 {
|
Chris@16
|
2487 return number_type();
|
Chris@16
|
2488 }
|
Chris@16
|
2489 static number_type lowest() { return (min)(); }
|
Chris@16
|
2490 BOOST_STATIC_CONSTEXPR int digits = INT_MAX;
|
Chris@16
|
2491 BOOST_STATIC_CONSTEXPR int digits10 = (INT_MAX / 1000) * 301L;
|
Chris@16
|
2492 BOOST_STATIC_CONSTEXPR int max_digits10 = digits10 + 2;
|
Chris@16
|
2493 BOOST_STATIC_CONSTEXPR bool is_signed = true;
|
Chris@16
|
2494 BOOST_STATIC_CONSTEXPR bool is_integer = true;
|
Chris@16
|
2495 BOOST_STATIC_CONSTEXPR bool is_exact = true;
|
Chris@16
|
2496 BOOST_STATIC_CONSTEXPR int radix = 2;
|
Chris@16
|
2497 static number_type epsilon() { return number_type(); }
|
Chris@16
|
2498 static number_type round_error() { return number_type(); }
|
Chris@16
|
2499 BOOST_STATIC_CONSTEXPR int min_exponent = 0;
|
Chris@16
|
2500 BOOST_STATIC_CONSTEXPR int min_exponent10 = 0;
|
Chris@16
|
2501 BOOST_STATIC_CONSTEXPR int max_exponent = 0;
|
Chris@16
|
2502 BOOST_STATIC_CONSTEXPR int max_exponent10 = 0;
|
Chris@16
|
2503 BOOST_STATIC_CONSTEXPR bool has_infinity = false;
|
Chris@16
|
2504 BOOST_STATIC_CONSTEXPR bool has_quiet_NaN = false;
|
Chris@16
|
2505 BOOST_STATIC_CONSTEXPR bool has_signaling_NaN = false;
|
Chris@16
|
2506 BOOST_STATIC_CONSTEXPR float_denorm_style has_denorm = denorm_absent;
|
Chris@16
|
2507 BOOST_STATIC_CONSTEXPR bool has_denorm_loss = false;
|
Chris@16
|
2508 static number_type infinity() { return number_type(); }
|
Chris@16
|
2509 static number_type quiet_NaN() { return number_type(); }
|
Chris@16
|
2510 static number_type signaling_NaN() { return number_type(); }
|
Chris@16
|
2511 static number_type denorm_min() { return number_type(); }
|
Chris@16
|
2512 BOOST_STATIC_CONSTEXPR bool is_iec559 = false;
|
Chris@16
|
2513 BOOST_STATIC_CONSTEXPR bool is_bounded = false;
|
Chris@16
|
2514 BOOST_STATIC_CONSTEXPR bool is_modulo = false;
|
Chris@16
|
2515 BOOST_STATIC_CONSTEXPR bool traps = false;
|
Chris@16
|
2516 BOOST_STATIC_CONSTEXPR bool tinyness_before = false;
|
Chris@16
|
2517 BOOST_STATIC_CONSTEXPR float_round_style round_style = round_toward_zero;
|
Chris@16
|
2518 };
|
Chris@16
|
2519
|
Chris@16
|
2520 #ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION
|
Chris@16
|
2521
|
Chris@16
|
2522 template <boost::multiprecision::expression_template_option ExpressionTemplates>
|
Chris@16
|
2523 BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_int, ExpressionTemplates> >::digits;
|
Chris@16
|
2524 template <boost::multiprecision::expression_template_option ExpressionTemplates>
|
Chris@16
|
2525 BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_int, ExpressionTemplates> >::digits10;
|
Chris@16
|
2526 template <boost::multiprecision::expression_template_option ExpressionTemplates>
|
Chris@16
|
2527 BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_int, ExpressionTemplates> >::max_digits10;
|
Chris@16
|
2528 template <boost::multiprecision::expression_template_option ExpressionTemplates>
|
Chris@16
|
2529 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_int, ExpressionTemplates> >::is_signed;
|
Chris@16
|
2530 template <boost::multiprecision::expression_template_option ExpressionTemplates>
|
Chris@16
|
2531 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_int, ExpressionTemplates> >::is_integer;
|
Chris@16
|
2532 template <boost::multiprecision::expression_template_option ExpressionTemplates>
|
Chris@16
|
2533 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_int, ExpressionTemplates> >::is_exact;
|
Chris@16
|
2534 template <boost::multiprecision::expression_template_option ExpressionTemplates>
|
Chris@16
|
2535 BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_int, ExpressionTemplates> >::radix;
|
Chris@16
|
2536 template <boost::multiprecision::expression_template_option ExpressionTemplates>
|
Chris@16
|
2537 BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_int, ExpressionTemplates> >::min_exponent;
|
Chris@16
|
2538 template <boost::multiprecision::expression_template_option ExpressionTemplates>
|
Chris@16
|
2539 BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_int, ExpressionTemplates> >::min_exponent10;
|
Chris@16
|
2540 template <boost::multiprecision::expression_template_option ExpressionTemplates>
|
Chris@16
|
2541 BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_int, ExpressionTemplates> >::max_exponent;
|
Chris@16
|
2542 template <boost::multiprecision::expression_template_option ExpressionTemplates>
|
Chris@16
|
2543 BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_int, ExpressionTemplates> >::max_exponent10;
|
Chris@16
|
2544 template <boost::multiprecision::expression_template_option ExpressionTemplates>
|
Chris@16
|
2545 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_int, ExpressionTemplates> >::has_infinity;
|
Chris@16
|
2546 template <boost::multiprecision::expression_template_option ExpressionTemplates>
|
Chris@16
|
2547 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_int, ExpressionTemplates> >::has_quiet_NaN;
|
Chris@16
|
2548 template <boost::multiprecision::expression_template_option ExpressionTemplates>
|
Chris@16
|
2549 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_int, ExpressionTemplates> >::has_signaling_NaN;
|
Chris@16
|
2550 template <boost::multiprecision::expression_template_option ExpressionTemplates>
|
Chris@16
|
2551 BOOST_CONSTEXPR_OR_CONST float_denorm_style numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_int, ExpressionTemplates> >::has_denorm;
|
Chris@16
|
2552 template <boost::multiprecision::expression_template_option ExpressionTemplates>
|
Chris@16
|
2553 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_int, ExpressionTemplates> >::has_denorm_loss;
|
Chris@16
|
2554 template <boost::multiprecision::expression_template_option ExpressionTemplates>
|
Chris@16
|
2555 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_int, ExpressionTemplates> >::is_iec559;
|
Chris@16
|
2556 template <boost::multiprecision::expression_template_option ExpressionTemplates>
|
Chris@16
|
2557 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_int, ExpressionTemplates> >::is_bounded;
|
Chris@16
|
2558 template <boost::multiprecision::expression_template_option ExpressionTemplates>
|
Chris@16
|
2559 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_int, ExpressionTemplates> >::is_modulo;
|
Chris@16
|
2560 template <boost::multiprecision::expression_template_option ExpressionTemplates>
|
Chris@16
|
2561 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_int, ExpressionTemplates> >::traps;
|
Chris@16
|
2562 template <boost::multiprecision::expression_template_option ExpressionTemplates>
|
Chris@16
|
2563 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_int, ExpressionTemplates> >::tinyness_before;
|
Chris@16
|
2564 template <boost::multiprecision::expression_template_option ExpressionTemplates>
|
Chris@16
|
2565 BOOST_CONSTEXPR_OR_CONST float_round_style numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_int, ExpressionTemplates> >::round_style;
|
Chris@16
|
2566
|
Chris@16
|
2567 #endif
|
Chris@16
|
2568
|
Chris@16
|
2569 template<boost::multiprecision::expression_template_option ExpressionTemplates>
|
Chris@16
|
2570 class numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_rational, ExpressionTemplates> >
|
Chris@16
|
2571 {
|
Chris@16
|
2572 typedef boost::multiprecision::number<boost::multiprecision::gmp_rational, ExpressionTemplates> number_type;
|
Chris@16
|
2573 public:
|
Chris@16
|
2574 BOOST_STATIC_CONSTEXPR bool is_specialized = true;
|
Chris@16
|
2575 //
|
Chris@16
|
2576 // Largest and smallest numbers are bounded only by available memory, set
|
Chris@16
|
2577 // to zero:
|
Chris@16
|
2578 //
|
Chris@16
|
2579 static number_type (min)()
|
Chris@16
|
2580 {
|
Chris@16
|
2581 return number_type();
|
Chris@16
|
2582 }
|
Chris@16
|
2583 static number_type (max)()
|
Chris@16
|
2584 {
|
Chris@16
|
2585 return number_type();
|
Chris@16
|
2586 }
|
Chris@16
|
2587 static number_type lowest() { return (min)(); }
|
Chris@16
|
2588 // Digits are unbounded, use zero for now:
|
Chris@16
|
2589 BOOST_STATIC_CONSTEXPR int digits = INT_MAX;
|
Chris@16
|
2590 BOOST_STATIC_CONSTEXPR int digits10 = (INT_MAX / 1000) * 301L;
|
Chris@16
|
2591 BOOST_STATIC_CONSTEXPR int max_digits10 = digits10 + 2;
|
Chris@16
|
2592 BOOST_STATIC_CONSTEXPR bool is_signed = true;
|
Chris@16
|
2593 BOOST_STATIC_CONSTEXPR bool is_integer = false;
|
Chris@16
|
2594 BOOST_STATIC_CONSTEXPR bool is_exact = true;
|
Chris@16
|
2595 BOOST_STATIC_CONSTEXPR int radix = 2;
|
Chris@16
|
2596 static number_type epsilon() { return number_type(); }
|
Chris@16
|
2597 static number_type round_error() { return number_type(); }
|
Chris@16
|
2598 BOOST_STATIC_CONSTEXPR int min_exponent = 0;
|
Chris@16
|
2599 BOOST_STATIC_CONSTEXPR int min_exponent10 = 0;
|
Chris@16
|
2600 BOOST_STATIC_CONSTEXPR int max_exponent = 0;
|
Chris@16
|
2601 BOOST_STATIC_CONSTEXPR int max_exponent10 = 0;
|
Chris@16
|
2602 BOOST_STATIC_CONSTEXPR bool has_infinity = false;
|
Chris@16
|
2603 BOOST_STATIC_CONSTEXPR bool has_quiet_NaN = false;
|
Chris@16
|
2604 BOOST_STATIC_CONSTEXPR bool has_signaling_NaN = false;
|
Chris@16
|
2605 BOOST_STATIC_CONSTEXPR float_denorm_style has_denorm = denorm_absent;
|
Chris@16
|
2606 BOOST_STATIC_CONSTEXPR bool has_denorm_loss = false;
|
Chris@16
|
2607 static number_type infinity() { return number_type(); }
|
Chris@16
|
2608 static number_type quiet_NaN() { return number_type(); }
|
Chris@16
|
2609 static number_type signaling_NaN() { return number_type(); }
|
Chris@16
|
2610 static number_type denorm_min() { return number_type(); }
|
Chris@16
|
2611 BOOST_STATIC_CONSTEXPR bool is_iec559 = false;
|
Chris@16
|
2612 BOOST_STATIC_CONSTEXPR bool is_bounded = false;
|
Chris@16
|
2613 BOOST_STATIC_CONSTEXPR bool is_modulo = false;
|
Chris@16
|
2614 BOOST_STATIC_CONSTEXPR bool traps = false;
|
Chris@16
|
2615 BOOST_STATIC_CONSTEXPR bool tinyness_before = false;
|
Chris@16
|
2616 BOOST_STATIC_CONSTEXPR float_round_style round_style = round_toward_zero;
|
Chris@16
|
2617 };
|
Chris@16
|
2618
|
Chris@16
|
2619 #ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION
|
Chris@16
|
2620
|
Chris@16
|
2621 template <boost::multiprecision::expression_template_option ExpressionTemplates>
|
Chris@16
|
2622 BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_rational, ExpressionTemplates> >::digits;
|
Chris@16
|
2623 template <boost::multiprecision::expression_template_option ExpressionTemplates>
|
Chris@16
|
2624 BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_rational, ExpressionTemplates> >::digits10;
|
Chris@16
|
2625 template <boost::multiprecision::expression_template_option ExpressionTemplates>
|
Chris@16
|
2626 BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_rational, ExpressionTemplates> >::max_digits10;
|
Chris@16
|
2627 template <boost::multiprecision::expression_template_option ExpressionTemplates>
|
Chris@16
|
2628 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_rational, ExpressionTemplates> >::is_signed;
|
Chris@16
|
2629 template <boost::multiprecision::expression_template_option ExpressionTemplates>
|
Chris@16
|
2630 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_rational, ExpressionTemplates> >::is_integer;
|
Chris@16
|
2631 template <boost::multiprecision::expression_template_option ExpressionTemplates>
|
Chris@16
|
2632 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_rational, ExpressionTemplates> >::is_exact;
|
Chris@16
|
2633 template <boost::multiprecision::expression_template_option ExpressionTemplates>
|
Chris@16
|
2634 BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_rational, ExpressionTemplates> >::radix;
|
Chris@16
|
2635 template <boost::multiprecision::expression_template_option ExpressionTemplates>
|
Chris@16
|
2636 BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_rational, ExpressionTemplates> >::min_exponent;
|
Chris@16
|
2637 template <boost::multiprecision::expression_template_option ExpressionTemplates>
|
Chris@16
|
2638 BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_rational, ExpressionTemplates> >::min_exponent10;
|
Chris@16
|
2639 template <boost::multiprecision::expression_template_option ExpressionTemplates>
|
Chris@16
|
2640 BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_rational, ExpressionTemplates> >::max_exponent;
|
Chris@16
|
2641 template <boost::multiprecision::expression_template_option ExpressionTemplates>
|
Chris@16
|
2642 BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_rational, ExpressionTemplates> >::max_exponent10;
|
Chris@16
|
2643 template <boost::multiprecision::expression_template_option ExpressionTemplates>
|
Chris@16
|
2644 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_rational, ExpressionTemplates> >::has_infinity;
|
Chris@16
|
2645 template <boost::multiprecision::expression_template_option ExpressionTemplates>
|
Chris@16
|
2646 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_rational, ExpressionTemplates> >::has_quiet_NaN;
|
Chris@16
|
2647 template <boost::multiprecision::expression_template_option ExpressionTemplates>
|
Chris@16
|
2648 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_rational, ExpressionTemplates> >::has_signaling_NaN;
|
Chris@16
|
2649 template <boost::multiprecision::expression_template_option ExpressionTemplates>
|
Chris@16
|
2650 BOOST_CONSTEXPR_OR_CONST float_denorm_style numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_rational, ExpressionTemplates> >::has_denorm;
|
Chris@16
|
2651 template <boost::multiprecision::expression_template_option ExpressionTemplates>
|
Chris@16
|
2652 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_rational, ExpressionTemplates> >::has_denorm_loss;
|
Chris@16
|
2653 template <boost::multiprecision::expression_template_option ExpressionTemplates>
|
Chris@16
|
2654 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_rational, ExpressionTemplates> >::is_iec559;
|
Chris@16
|
2655 template <boost::multiprecision::expression_template_option ExpressionTemplates>
|
Chris@16
|
2656 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_rational, ExpressionTemplates> >::is_bounded;
|
Chris@16
|
2657 template <boost::multiprecision::expression_template_option ExpressionTemplates>
|
Chris@16
|
2658 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_rational, ExpressionTemplates> >::is_modulo;
|
Chris@16
|
2659 template <boost::multiprecision::expression_template_option ExpressionTemplates>
|
Chris@16
|
2660 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_rational, ExpressionTemplates> >::traps;
|
Chris@16
|
2661 template <boost::multiprecision::expression_template_option ExpressionTemplates>
|
Chris@16
|
2662 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_rational, ExpressionTemplates> >::tinyness_before;
|
Chris@16
|
2663 template <boost::multiprecision::expression_template_option ExpressionTemplates>
|
Chris@16
|
2664 BOOST_CONSTEXPR_OR_CONST float_round_style numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_rational, ExpressionTemplates> >::round_style;
|
Chris@16
|
2665
|
Chris@16
|
2666 #endif
|
Chris@16
|
2667
|
Chris@16
|
2668 #ifdef BOOST_MSVC
|
Chris@16
|
2669 #pragma warning(pop)
|
Chris@16
|
2670 #endif
|
Chris@16
|
2671
|
Chris@16
|
2672 } // namespace std
|
Chris@16
|
2673
|
Chris@16
|
2674 #endif
|