PPL  1.2
checked_mpz_inlines.hh
Go to the documentation of this file.
1 /* Specialized "checked" functions for GMP's mpz_class numbers.
2  Copyright (C) 2001-2010 Roberto Bagnara <bagnara@cs.unipr.it>
3  Copyright (C) 2010-2016 BUGSENG srl (http://bugseng.com)
4 
5 This file is part of the Parma Polyhedra Library (PPL).
6 
7 The PPL is free software; you can redistribute it and/or modify it
8 under the terms of the GNU General Public License as published by the
9 Free Software Foundation; either version 3 of the License, or (at your
10 option) any later version.
11 
12 The PPL is distributed in the hope that it will be useful, but WITHOUT
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 for more details.
16 
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software Foundation,
19 Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1307, USA.
20 
21 For the most up-to-date information see the Parma Polyhedra Library
22 site: http://bugseng.com/products/ppl/ . */
23 
24 #ifndef PPL_checked_mpz_inlines_hh
25 #define PPL_checked_mpz_inlines_hh 1
26 
27 #include <sstream>
28 
29 namespace Parma_Polyhedra_Library {
30 
31 namespace Checked {
32 
33 template <typename Policy>
34 inline Result
35 round_lt_mpz(mpz_class& to, Rounding_Dir dir) {
36  if (round_down(dir)) {
37  --to;
38  return V_GT;
39  }
40  return V_LT;
41 }
42 
43 template <typename Policy>
44 inline Result
45 round_gt_mpz(mpz_class& to, Rounding_Dir dir) {
46  if (round_up(dir)) {
47  ++to;
48  return V_LT;
49  }
50  return V_GT;
51 }
52 
53 #if __cplusplus >= 201103L
54 typedef decltype(__mpz_struct()._mp_size) mp_size_field_t;
56 #elif PPL_HAVE_TYPEOF
57 typedef typeof(__mpz_struct()._mp_size) mp_size_field_t;
59 #else
60 typedef int mp_size_field_t;
62 #endif
63 
64 inline mp_size_field_t
65 get_mp_size(const mpz_class &v) {
66  return v.get_mpz_t()->_mp_size;
67 }
68 
69 inline void
70 set_mp_size(mpz_class &v, mp_size_field_t size) {
71  v.get_mpz_t()->_mp_size = size;
72 }
73 
74 template <typename Policy>
75 inline Result
76 classify_mpz(const mpz_class& v, bool nan, bool inf, bool sign) {
77  if (Policy::has_nan || Policy::has_infinity) {
78  mp_size_field_t s = get_mp_size(v);
79  if (Policy::has_nan
80  && (nan || sign)
81  && s == C_Integer<mp_size_field_t>::min + 1) {
82  return V_NAN;
83  }
84  if (!inf && !sign) {
85  return V_LGE;
86  }
87  if (Policy::has_infinity) {
89  return inf ? V_EQ_MINUS_INFINITY : V_LT;
90  }
92  return inf ? V_EQ_PLUS_INFINITY : V_GT;
93  }
94  }
95  }
96  if (sign) {
97  return static_cast<Result>(sgn<Policy>(v));
98  }
99  return V_LGE;
100 }
101 
103 
104 template <typename Policy>
105 inline bool
106 is_nan_mpz(const mpz_class& v) {
107  return Policy::has_nan
109 }
110 
112 
113 template <typename Policy>
114 inline bool
115 is_minf_mpz(const mpz_class& v) {
116  return Policy::has_infinity
118 }
119 
121 
122 template <typename Policy>
123 inline bool
124 is_pinf_mpz(const mpz_class& v) {
125  return Policy::has_infinity
127 }
128 
130 
131 template <typename Policy>
132 inline bool
133 is_int_mpz(const mpz_class& v) {
134  return !is_nan<Policy>(v);
135 }
136 
138 
139 template <typename Policy>
140 inline Result
142  switch (c) {
143  case VC_NAN:
144  if (Policy::has_nan) {
146  }
147  return V_NAN;
148  case VC_MINUS_INFINITY:
149  if (Policy::has_infinity) {
151  return V_EQ_MINUS_INFINITY;
152  }
154  case VC_PLUS_INFINITY:
155  if (Policy::has_infinity) {
157  return V_EQ_PLUS_INFINITY;
158  }
160  default:
161  PPL_UNREACHABLE;
162  return V_NAN;
163  }
164 }
165 
167 
168 template <typename To_Policy, typename From_Policy>
169 inline void
170 copy_mpz(mpz_class& to, const mpz_class& from) {
171  if (is_nan_mpz<From_Policy>(from)) {
172  PPL_ASSERT(To_Policy::has_nan);
173  }
174  else if (is_minf_mpz<From_Policy>(from) || is_pinf_mpz<From_Policy>(from)) {
175  PPL_ASSERT(To_Policy::has_infinity);
176  }
177  else {
178  to = from;
179  return;
180  }
181  set_mp_size(to, get_mp_size(from));
182 }
183 
184 PPL_SPECIALIZE_COPY(copy_mpz, mpz_class)
185 
186 template <typename To_Policy, typename From_Policy, typename From>
187 inline Result
188 construct_mpz_base(mpz_class& to, const From from, Rounding_Dir) {
189  new(&to) mpz_class(from);
190  return V_EQ;
191 }
192 
194 PPL_SPECIALIZE_CONSTRUCT(construct_mpz_base, mpz_class, signed char)
195 PPL_SPECIALIZE_CONSTRUCT(construct_mpz_base, mpz_class, signed short)
196 PPL_SPECIALIZE_CONSTRUCT(construct_mpz_base, mpz_class, signed int)
197 PPL_SPECIALIZE_CONSTRUCT(construct_mpz_base, mpz_class, signed long)
198 PPL_SPECIALIZE_CONSTRUCT(construct_mpz_base, mpz_class, unsigned char)
199 PPL_SPECIALIZE_CONSTRUCT(construct_mpz_base, mpz_class, unsigned short)
200 PPL_SPECIALIZE_CONSTRUCT(construct_mpz_base, mpz_class, unsigned int)
201 PPL_SPECIALIZE_CONSTRUCT(construct_mpz_base, mpz_class, unsigned long)
202 
203 template <typename To_Policy, typename From_Policy, typename From>
204 inline Result
205 construct_mpz_float(mpz_class& to, const From& from, Rounding_Dir dir) {
206  if (is_nan<From_Policy>(from)) {
207  return construct_special<To_Policy>(to, VC_NAN, ROUND_IGNORE);
208  }
209  else if (is_minf<From_Policy>(from)) {
210  return construct_special<To_Policy>(to, VC_MINUS_INFINITY, dir);
211  }
212  else if (is_pinf<From_Policy>(from)) {
213  return construct_special<To_Policy>(to, VC_PLUS_INFINITY, dir);
214  }
215  if (round_not_requested(dir)) {
216  new(&to) mpz_class(from);
217  return V_LGE;
218  }
219  From n = rint(from);
220  new(&to) mpz_class(n);
221  if (from == n) {
222  return V_EQ;
223  }
224  if (from < 0) {
225  return round_lt_mpz<To_Policy>(to, dir);
226  }
227  else {
228  return round_gt_mpz<To_Policy>(to, dir);
229  }
230 }
231 
234 
235 PPL_SPECIALIZE_ASSIGN(assign_exact, mpz_class, mpz_class)
236 PPL_SPECIALIZE_ASSIGN(assign_exact, mpz_class, char)
237 PPL_SPECIALIZE_ASSIGN(assign_exact, mpz_class, signed char)
238 PPL_SPECIALIZE_ASSIGN(assign_exact, mpz_class, signed short)
239 PPL_SPECIALIZE_ASSIGN(assign_exact, mpz_class, signed int)
240 PPL_SPECIALIZE_ASSIGN(assign_exact, mpz_class, signed long)
241 PPL_SPECIALIZE_ASSIGN(assign_exact, mpz_class, unsigned char)
242 PPL_SPECIALIZE_ASSIGN(assign_exact, mpz_class, unsigned short)
243 PPL_SPECIALIZE_ASSIGN(assign_exact, mpz_class, unsigned int)
244 PPL_SPECIALIZE_ASSIGN(assign_exact, mpz_class, unsigned long)
245 
246 template <typename To_Policy, typename From_Policy, typename From>
247 inline Result
249  if (sizeof(From) <= sizeof(signed long)) {
250  to = static_cast<signed long>(from);
251  }
252  else {
253  mpz_ptr m = to.get_mpz_t();
254  if (from >= 0) {
255  mpz_import(m, 1, 1, sizeof(From), 0, 0, &from);
256  }
257  else {
258  From n = -from;
259  mpz_import(m, 1, 1, sizeof(From), 0, 0, &n);
260  mpz_neg(m, m);
261  }
262  }
263  return V_EQ;
264 }
265 
266 PPL_SPECIALIZE_ASSIGN(assign_mpz_signed_int, mpz_class, signed long long)
267 
268 template <typename To_Policy, typename From_Policy, typename From>
269 inline Result
270 assign_mpz_unsigned_int(mpz_class& to, const From from, Rounding_Dir) {
271  if (sizeof(From) <= sizeof(unsigned long)) {
272  to = static_cast<unsigned long>(from);
273  }
274  else {
275  mpz_import(to.get_mpz_t(), 1, 1, sizeof(From), 0, 0, &from);
276  }
277  return V_EQ;
278 }
279 
280 PPL_SPECIALIZE_ASSIGN(assign_mpz_unsigned_int, mpz_class, unsigned long long)
281 
282 template <typename To_Policy, typename From_Policy, typename From>
283 inline Result
284 assign_mpz_float(mpz_class& to, const From from, Rounding_Dir dir) {
285  if (is_nan<From_Policy>(from)) {
286  return assign_special<To_Policy>(to, VC_NAN, ROUND_IGNORE);
287  }
288  else if (is_minf<From_Policy>(from)) {
289  return assign_special<To_Policy>(to, VC_MINUS_INFINITY, dir);
290  }
291  else if (is_pinf<From_Policy>(from)) {
292  return assign_special<To_Policy>(to, VC_PLUS_INFINITY, dir);
293  }
294  if (round_not_requested(dir)) {
295  to = from;
296  return V_LGE;
297  }
298  From i_from = rint(from);
299  to = i_from;
300  if (from == i_from) {
301  return V_EQ;
302  }
303  if (round_direct(ROUND_UP)) {
304  return round_lt_mpz<To_Policy>(to, dir);
305  }
306  if (round_direct(ROUND_DOWN)) {
307  return round_gt_mpz<To_Policy>(to, dir);
308  }
309  if (from < i_from) {
310  return round_lt_mpz<To_Policy>(to, dir);
311  }
312  if (from > i_from) {
313  return round_gt_mpz<To_Policy>(to, dir);
314  }
315  PPL_UNREACHABLE;
316  return V_NAN;
317 }
318 
319 PPL_SPECIALIZE_ASSIGN(assign_mpz_float, mpz_class, float)
320 PPL_SPECIALIZE_ASSIGN(assign_mpz_float, mpz_class, double)
321 
322 template <typename To_Policy, typename From_Policy, typename From>
323 inline Result
324 assign_mpz_long_double(mpz_class& to, const From& from, Rounding_Dir dir) {
325  if (is_nan<From_Policy>(from)) {
326  return assign_special<To_Policy>(to, VC_NAN, ROUND_IGNORE);
327  }
328  else if (is_minf<From_Policy>(from)) {
329  return assign_special<To_Policy>(to, VC_MINUS_INFINITY, dir);
330  }
331  else if (is_pinf<From_Policy>(from)) {
332  return assign_special<To_Policy>(to, VC_PLUS_INFINITY, dir);
333  }
334  // FIXME: this is an incredibly inefficient implementation!
335  std::stringstream ss;
336  output<From_Policy>(ss, from, Numeric_Format(), dir);
337  PPL_DIRTY_TEMP(mpq_class, tmp);
338 #ifndef NDEBUG
339  Result r =
340 #endif
341  input_mpq(tmp, ss);
342  PPL_ASSERT(r == V_EQ);
343  return assign<To_Policy, From_Policy>(to, tmp, dir);
344 }
345 
346 PPL_SPECIALIZE_ASSIGN(assign_mpz_long_double, mpz_class, long double)
347 
348 template <typename To_Policy, typename From_Policy>
349 inline Result
350 assign_mpz_mpq(mpz_class& to, const mpq_class& from, Rounding_Dir dir) {
351  if (round_not_needed(dir)) {
352  to = from.get_num();
353  return V_LGE;
354  }
355  if (round_ignore(dir)) {
356  to = from;
357  return V_LGE;
358  }
359  const mpz_srcptr n = from.get_num().get_mpz_t();
360  const mpz_srcptr d = from.get_den().get_mpz_t();
361  if (round_down(dir)) {
362  mpz_fdiv_q(to.get_mpz_t(), n, d);
363  if (round_strict_relation(dir)) {
364  return (mpz_divisible_p(n, d) != 0) ? V_EQ : V_GT;
365  }
366  return V_GE;
367  }
368  else {
369  PPL_ASSERT(round_up(dir));
370  mpz_cdiv_q(to.get_mpz_t(), n, d);
371  if (round_strict_relation(dir)) {
372  return (mpz_divisible_p(n, d) != 0) ? V_EQ : V_LT;
373  }
374  return V_LE;
375  }
376 }
377 
378 PPL_SPECIALIZE_ASSIGN(assign_mpz_mpq, mpz_class, mpq_class)
379 
380 PPL_SPECIALIZE_FLOOR(assign_exact, mpz_class, mpz_class)
381 PPL_SPECIALIZE_CEIL(assign_exact, mpz_class, mpz_class)
382 PPL_SPECIALIZE_TRUNC(assign_exact, mpz_class, mpz_class)
383 
384 template <typename To_Policy, typename From_Policy>
385 inline Result
386 neg_mpz(mpz_class& to, const mpz_class& from, Rounding_Dir) {
387  mpz_neg(to.get_mpz_t(), from.get_mpz_t());
388  return V_EQ;
389 }
390 
391 PPL_SPECIALIZE_NEG(neg_mpz, mpz_class, mpz_class)
392 
393 template <typename To_Policy, typename From1_Policy, typename From2_Policy>
394 inline Result
395 add_mpz(mpz_class& to, const mpz_class& x, const mpz_class& y, Rounding_Dir) {
396  to = x + y;
397  return V_EQ;
398 }
399 
400 PPL_SPECIALIZE_ADD(add_mpz, mpz_class, mpz_class, mpz_class)
401 
402 template <typename To_Policy, typename From1_Policy, typename From2_Policy>
403 inline Result
404 sub_mpz(mpz_class& to, const mpz_class& x, const mpz_class& y, Rounding_Dir) {
405  to = x - y;
406  return V_EQ;
407 }
408 
409 PPL_SPECIALIZE_SUB(sub_mpz, mpz_class, mpz_class, mpz_class)
410 
411 template <typename To_Policy, typename From1_Policy, typename From2_Policy>
412 inline Result
413 mul_mpz(mpz_class& to, const mpz_class& x, const mpz_class& y, Rounding_Dir) {
414  to = x * y;
415  return V_EQ;
416 }
417 
418 PPL_SPECIALIZE_MUL(mul_mpz, mpz_class, mpz_class, mpz_class)
419 
420 template <typename To_Policy, typename From1_Policy, typename From2_Policy>
421 inline Result
422 div_mpz(mpz_class& to, const mpz_class& x, const mpz_class& y,
423  Rounding_Dir dir) {
424  if (CHECK_P(To_Policy::check_div_zero, ::sgn(y) == 0)) {
425  return assign_nan<To_Policy>(to, V_DIV_ZERO);
426  }
427  const mpz_srcptr n = x.get_mpz_t();
428  const mpz_srcptr d = y.get_mpz_t();
429  if (round_not_needed(dir)) {
430  mpz_divexact(to.get_mpz_t(), n, d);
431  return V_LGE;
432  }
433  if (round_ignore(dir)) {
434  mpz_cdiv_q(to.get_mpz_t(), n, d);
435  return V_LE;
436  }
437  if (round_down(dir)) {
438  mpz_fdiv_q(to.get_mpz_t(), n, d);
439  if (round_strict_relation(dir)) {
440  return (mpz_divisible_p(n, d) != 0) ? V_EQ : V_GT;
441  }
442  return V_GE;
443  }
444  else {
445  PPL_ASSERT(round_up(dir));
446  mpz_cdiv_q(to.get_mpz_t(), n, d);
447  if (round_strict_relation(dir)) {
448  return (mpz_divisible_p(n, d) != 0) ? V_EQ : V_LT;
449  }
450  return V_LE;
451  }
452 }
453 
454 PPL_SPECIALIZE_DIV(div_mpz, mpz_class, mpz_class, mpz_class)
455 
456 template <typename To_Policy, typename From1_Policy, typename From2_Policy>
457 inline Result
458 idiv_mpz(mpz_class& to, const mpz_class& x, const mpz_class& y,
459  Rounding_Dir) {
460  if (CHECK_P(To_Policy::check_div_zero, ::sgn(y) == 0)) {
461  return assign_nan<To_Policy>(to, V_DIV_ZERO);
462  }
463  mpz_srcptr n = x.get_mpz_t();
464  mpz_srcptr d = y.get_mpz_t();
465  mpz_tdiv_q(to.get_mpz_t(), n, d);
466  return V_EQ;
467 }
468 
469 PPL_SPECIALIZE_IDIV(idiv_mpz, mpz_class, mpz_class, mpz_class)
470 
471 template <typename To_Policy, typename From1_Policy, typename From2_Policy>
472 inline Result
473 rem_mpz(mpz_class& to, const mpz_class& x, const mpz_class& y, Rounding_Dir) {
474  if (CHECK_P(To_Policy::check_div_zero, ::sgn(y) == 0)) {
475  return assign_nan<To_Policy>(to, V_MOD_ZERO);
476  }
477  to = x % y;
478  return V_EQ;
479 }
480 
481 PPL_SPECIALIZE_REM(rem_mpz, mpz_class, mpz_class, mpz_class)
482 
483 template <typename To_Policy, typename From_Policy>
484 inline Result
485 add_2exp_mpz(mpz_class& to, const mpz_class& x, unsigned int exp,
486  Rounding_Dir) {
487  PPL_DIRTY_TEMP(mpz_class, v);
488  v = 1;
489  mpz_mul_2exp(v.get_mpz_t(), v.get_mpz_t(), exp);
490  to = x + v;
491  return V_EQ;
492 }
493 
494 PPL_SPECIALIZE_ADD_2EXP(add_2exp_mpz, mpz_class, mpz_class)
495 
496 template <typename To_Policy, typename From_Policy>
497 inline Result
498 sub_2exp_mpz(mpz_class& to, const mpz_class& x, unsigned int exp,
499  Rounding_Dir) {
500  PPL_DIRTY_TEMP(mpz_class, v);
501  v = 1;
502  mpz_mul_2exp(v.get_mpz_t(), v.get_mpz_t(), exp);
503  to = x - v;
504  return V_EQ;
505 }
506 
507 PPL_SPECIALIZE_SUB_2EXP(sub_2exp_mpz, mpz_class, mpz_class)
508 
509 template <typename To_Policy, typename From_Policy>
510 inline Result
511 mul_2exp_mpz(mpz_class& to, const mpz_class& x, unsigned int exp,
512  Rounding_Dir) {
513  mpz_mul_2exp(to.get_mpz_t(), x.get_mpz_t(), exp);
514  return V_EQ;
515 }
516 
517 PPL_SPECIALIZE_MUL_2EXP(mul_2exp_mpz, mpz_class, mpz_class)
518 
519 template <typename To_Policy, typename From_Policy>
520 inline Result
521 div_2exp_mpz(mpz_class& to, const mpz_class& x, unsigned int exp,
522  Rounding_Dir dir) {
523  const mpz_srcptr n = x.get_mpz_t();
524  if (round_not_requested(dir)) {
525  mpz_tdiv_q_2exp(to.get_mpz_t(), x.get_mpz_t(), exp);
526  return V_LGE;
527  }
528  if (round_down(dir)) {
529  mpz_fdiv_q_2exp(to.get_mpz_t(), n, exp);
530  if (round_strict_relation(dir)) {
531  return (mpz_divisible_2exp_p(n, exp) != 0) ? V_EQ : V_GT;
532  }
533  return V_GE;
534  }
535  else {
536  PPL_ASSERT(round_up(dir));
537  mpz_cdiv_q_2exp(to.get_mpz_t(), n, exp);
538  if (round_strict_relation(dir)) {
539  return (mpz_divisible_2exp_p(n, exp) != 0) ? V_EQ : V_LT;
540  }
541  return V_LE;
542  }
543 }
544 
545 PPL_SPECIALIZE_DIV_2EXP(div_2exp_mpz, mpz_class, mpz_class)
546 
547 template <typename To_Policy, typename From_Policy>
548 inline Result
549 smod_2exp_mpz(mpz_class& to, const mpz_class& x, unsigned int exp,
550  Rounding_Dir) {
551  if (mpz_tstbit(x.get_mpz_t(), exp - 1) != 0) {
552  mpz_cdiv_r_2exp(to.get_mpz_t(), x.get_mpz_t(), exp);
553  }
554  else {
555  mpz_fdiv_r_2exp(to.get_mpz_t(), x.get_mpz_t(), exp);
556  }
557  return V_EQ;
558 }
559 
560 PPL_SPECIALIZE_SMOD_2EXP(smod_2exp_mpz, mpz_class, mpz_class)
561 
562 template <typename To_Policy, typename From_Policy>
563 inline Result
564 umod_2exp_mpz(mpz_class& to, const mpz_class& x, unsigned int exp,
565  Rounding_Dir) {
566  mpz_fdiv_r_2exp(to.get_mpz_t(), x.get_mpz_t(), exp);
567  return V_EQ;
568 }
569 
570 PPL_SPECIALIZE_UMOD_2EXP(umod_2exp_mpz, mpz_class, mpz_class)
571 
572 template <typename To_Policy, typename From_Policy>
573 inline Result
574 abs_mpz(mpz_class& to, const mpz_class& from, Rounding_Dir) {
575  to = abs(from);
576  return V_EQ;
577 }
578 
579 PPL_SPECIALIZE_ABS(abs_mpz, mpz_class, mpz_class)
580 
581 template <typename To_Policy, typename From1_Policy, typename From2_Policy>
582 inline Result
583 add_mul_mpz(mpz_class& to, const mpz_class& x, const mpz_class& y,
584  Rounding_Dir) {
585  mpz_addmul(to.get_mpz_t(), x.get_mpz_t(), y.get_mpz_t());
586  return V_EQ;
587 }
588 
589 PPL_SPECIALIZE_ADD_MUL(add_mul_mpz, mpz_class, mpz_class, mpz_class)
590 
591 template <typename To_Policy, typename From1_Policy, typename From2_Policy>
592 inline Result
593 sub_mul_mpz(mpz_class& to, const mpz_class& x, const mpz_class& y,
594  Rounding_Dir) {
595  mpz_submul(to.get_mpz_t(), x.get_mpz_t(), y.get_mpz_t());
596  return V_EQ;
597 }
598 
599 PPL_SPECIALIZE_SUB_MUL(sub_mul_mpz, mpz_class, mpz_class, mpz_class)
600 
601 template <typename To_Policy, typename From1_Policy, typename From2_Policy>
602 inline Result
603 gcd_mpz(mpz_class& to, const mpz_class& x, const mpz_class& y, Rounding_Dir) {
604  mpz_gcd(to.get_mpz_t(), x.get_mpz_t(), y.get_mpz_t());
605  return V_EQ;
606 }
607 
608 PPL_SPECIALIZE_GCD(gcd_mpz, mpz_class, mpz_class, mpz_class)
609 
610 template <typename To_Policy, typename From1_Policy, typename From2_Policy>
611 inline Result
612 gcdext_mpz(mpz_class& to, mpz_class& s, mpz_class& t,
613  const mpz_class& x, const mpz_class& y,
614  Rounding_Dir) {
615  mpz_gcdext(to.get_mpz_t(), s.get_mpz_t(), t.get_mpz_t(),
616  x.get_mpz_t(), y.get_mpz_t());
617  return V_EQ;
618 }
619 
620 PPL_SPECIALIZE_GCDEXT(gcdext_mpz, mpz_class, mpz_class, mpz_class, mpz_class, mpz_class)
621 
622 template <typename To_Policy, typename From1_Policy, typename From2_Policy>
623 inline Result
624 lcm_mpz(mpz_class& to, const mpz_class& x, const mpz_class& y, Rounding_Dir) {
625  mpz_lcm(to.get_mpz_t(), x.get_mpz_t(), y.get_mpz_t());
626  return V_EQ;
627 }
628 
629 PPL_SPECIALIZE_LCM(lcm_mpz, mpz_class, mpz_class, mpz_class)
630 
631 template <typename To_Policy, typename From_Policy>
632 inline Result
633 sqrt_mpz(mpz_class& to, const mpz_class& from, Rounding_Dir dir) {
634  if (CHECK_P(To_Policy::check_sqrt_neg, from < 0)) {
635  return assign_nan<To_Policy>(to, V_SQRT_NEG);
636  }
637  if (round_not_requested(dir)) {
638  to = sqrt(from);
639  return V_GE;
640  }
641  PPL_DIRTY_TEMP(mpz_class, r);
642  mpz_sqrtrem(to.get_mpz_t(), r.get_mpz_t(), from.get_mpz_t());
643  if (r == 0) {
644  return V_EQ;
645  }
646  return round_gt_mpz<To_Policy>(to, dir);
647 }
648 
649 PPL_SPECIALIZE_SQRT(sqrt_mpz, mpz_class, mpz_class)
650 
651 template <typename Policy, typename Type>
652 inline Result_Relation
654  const int sign = ::sgn(x);
655  return (sign > 0) ? VR_GT : ((sign < 0) ? VR_LT : VR_EQ);
656 }
657 
658 PPL_SPECIALIZE_SGN(sgn_mp, mpz_class)
659 PPL_SPECIALIZE_SGN(sgn_mp, mpq_class)
660 
661 template <typename Policy1, typename Policy2, typename Type>
662 inline Result_Relation
664  int i = ::cmp(x, y);
665  return (i > 0) ? VR_GT : ((i < 0) ? VR_LT : VR_EQ);
666 }
667 
668 PPL_SPECIALIZE_CMP(cmp_mp, mpz_class, mpz_class)
669 PPL_SPECIALIZE_CMP(cmp_mp, mpq_class, mpq_class)
670 
671 template <typename Policy>
672 inline Result
673 output_mpz(std::ostream& os, const mpz_class& from, const Numeric_Format&,
674  Rounding_Dir) {
675  os << from;
676  return V_EQ;
677 }
678 
681 
682 } // namespace Checked
683 
684 } // namespace Parma_Polyhedra_Library
685 
686 #endif // !defined(PPL_checked_mpz_inlines_hh)
#define PPL_SPECIALIZE_NEG(func, To, From)
Result lcm_mpz(mpz_class &to, const mpz_class &x, const mpz_class &y, Rounding_Dir)
The computed result is exact.
Definition: Result_defs.hh:81
Result assign_mpz_unsigned_int(mpz_class &to, const From from, Rounding_Dir)
Taking the square root of a negative number.
Definition: Result_defs.hh:150
Result sqrt_mpz(mpz_class &to, const mpz_class &from, Rounding_Dir dir)
Result neg_mpz(mpz_class &to, const mpz_class &from, Rounding_Dir)
#define PPL_SPECIALIZE_ADD_MUL(func, To, From1, From2)
#define PPL_SPECIALIZE_IS_MINF(func, Type)
mp_size_field_t get_mp_size(const mpz_class &v)
Result mul_mpz(mpz_class &to, const mpz_class &x, const mpz_class &y, Rounding_Dir)
Rounding_Dir
Rounding directions for arithmetic computations.
#define PPL_SPECIALIZE_SQRT(func, To, From)
Result add_2exp_mpz(mpz_class &to, const mpz_class &x, unsigned int exp, Rounding_Dir)
Result assign_mpz_float(mpz_class &to, const From from, Rounding_Dir dir)
Computing a remainder modulo zero.
Definition: Result_defs.hh:147
void set_mp_size(mpz_class &v, mp_size_field_t size)
#define PPL_SPECIALIZE_CLASSIFY(func, Type)
bool round_ignore(Rounding_Dir dir)
#define PPL_SPECIALIZE_ADD(func, To, From1, From2)
bool round_strict_relation(Rounding_Dir dir)
int mp_size_field_t
This is assumed to be the type of the _mp_size field of GMP's __mpz_struct.
Result
Possible outcomes of a checked arithmetic computation.
Definition: Result_defs.hh:76
Result construct_mpz_base(mpz_class &to, const From from, Rounding_Dir)
The standard C++ namespace.
#define PPL_SPECIALIZE_REM(func, To, From1, From2)
Negative infinity result class.
Definition: Result_defs.hh:34
Not a number result class.
Definition: Result_defs.hh:40
Result classify_mpz(const mpz_class &v, bool nan, bool inf, bool sign)
bool is_nan_mpz(const mpz_class &v)
#define PPL_SPECIALIZE_ABS(func, To, From)
Result input_generic(Type &to, std::istream &is, Rounding_Dir dir)
Result idiv_mpz(mpz_class &to, const mpz_class &x, const mpz_class &y, Rounding_Dir)
#define PPL_SPECIALIZE_UMOD_2EXP(func, To, From)
Not a number result.
Definition: Result_defs.hh:123
PPL_SPECIALIZE_GCDEXT(gcdext_exact, char, char, char, char, char) PPL_SPECIALIZE_GCDEXT(gcdext_exact
Result construct_mpz_float(mpz_class &to, const From &from, Rounding_Dir dir)
The computed result is inexact and rounded down.
Definition: Result_defs.hh:87
Result round_gt_mpz(mpz_class &to, Rounding_Dir dir)
#define PPL_SPECIALIZE_TRUNC(func, To, From)
#define PPL_SPECIALIZE_CMP(func, Type1, Type2)
#define PPL_SPECIALIZE_CEIL(func, To, From)
#define PPL_SPECIALIZE_DIV(func, To, From1, From2)
void copy_mpz(mpz_class &to, const mpz_class &from)
Result add_mpz(mpz_class &to, const mpz_class &x, const mpz_class &y, Rounding_Dir)
Result div_2exp_mpz(mpz_class &to, const mpz_class &x, unsigned int exp, Rounding_Dir dir)
#define PPL_SPECIALIZE_IDIV(func, To, From1, From2)
Result mul_2exp_mpz(mpz_class &to, const mpz_class &x, unsigned int exp, Rounding_Dir)
Result sub_mul_mpz(mpz_class &to, const mpz_class &x, const mpz_class &y, Rounding_Dir)
#define PPL_SPECIALIZE_MUL_2EXP(func, To, From)
Result umod_2exp_mpz(mpz_class &to, const mpz_class &x, unsigned int exp, Rounding_Dir)
Positive infinity result class.
Definition: Result_defs.hh:37
Result gcdext_mpz(mpz_class &to, mpz_class &s, mpz_class &t, const mpz_class &x, const mpz_class &y, Rounding_Dir)
Result assign_mpz_long_double(mpz_class &to, const From &from, Rounding_Dir dir)
bool is_pinf_mpz(const mpz_class &v)
bool round_not_needed(Rounding_Dir dir)
The computed result is not representable.
Definition: Result_defs.hh:159
bool is_minf_mpz(const mpz_class &v)
Result add_mul_mpz(mpz_class &to, const mpz_class &x, const mpz_class &y, Rounding_Dir)
#define PPL_SPECIALIZE_SUB(func, To, From1, From2)
#define PPL_SPECIALIZE_ASSIGN_SPECIAL(func, Type)
bool is_int_mpz(const mpz_class &v)
Equal. This need to be accompanied by a value.
Definition: Result_defs.hh:51
Less than. This need to be accompanied by a value.
Definition: Result_defs.hh:54
Result sub_mpz(mpz_class &to, const mpz_class &x, const mpz_class &y, Rounding_Dir)
bool round_up(Rounding_Dir dir)
#define PPL_SPECIALIZE_ADD_2EXP(func, To, From)
Result round_lt_mpz(mpz_class &to, Rounding_Dir dir)
#define PPL_SPECIALIZE_GCD(func, To, From1, From2)
#define PPL_SPECIALIZE_SUB_MUL(func, To, From1, From2)
Result abs_mpz(mpz_class &to, const mpz_class &from, Rounding_Dir)
The computed result may be inexact and rounded up.
Definition: Result_defs.hh:93
Result assign_mpz_mpq(mpz_class &to, const mpq_class &from, Rounding_Dir dir)
#define PPL_DIRTY_TEMP(T, id)
#define PPL_SPECIALIZE_IS_INT(func, Type)
#define PPL_SPECIALIZE_FLOOR(func, To, From)
Result gcd_mpz(mpz_class &to, const mpz_class &x, const mpz_class &y, Rounding_Dir)
#define PPL_SPECIALIZE_CONSTRUCT(func, To, From)
Result sub_2exp_mpz(mpz_class &to, const mpz_class &x, unsigned int exp, Rounding_Dir)
Result assign_exact(To &to, const From &from, Rounding_Dir)
Result_Relation cmp_mp(const Type &x, const Type &y)
Result assign_mpz_signed_int(mpz_class &to, const From from, Rounding_Dir)
The entire library is confined to this namespace.
Definition: version.hh:61
#define PPL_SPECIALIZE_DIV_2EXP(func, To, From)
Result_Relation sgn_mp(const Type &x)
Greater than. This need to be accompanied by a value.
Definition: Result_defs.hh:57
bool round_direct(Rounding_Dir dir)
int cmp(const GMP_Integer &x, const GMP_Integer &y)
The computed result may be inexact and rounded down.
Definition: Result_defs.hh:96
From bool Type Type Rounding_Dir From
Result input_mpq(mpq_class &to, std::istream &is)
Definition: checked.cc:429
Result output_mpz(std::ostream &os, const mpz_class &from, const Numeric_Format &, Rounding_Dir)
#define PPL_SPECIALIZE_IS_NAN(func, Type)
int sgn(Boundary_Type type, const T &x, const Info &info)
#define PPL_SPECIALIZE_ASSIGN(func, To, From)
#define PPL_SPECIALIZE_SUB_2EXP(func, To, From)
Result rem_mpz(mpz_class &to, const mpz_class &x, const mpz_class &y, Rounding_Dir)
#define PPL_SPECIALIZE_COPY(func, Type)
Coefficient c
Definition: PIP_Tree.cc:64
Result assign_special_mpz(mpz_class &v, Result_Class c, Rounding_Dir)
#define PPL_SPECIALIZE_LCM(func, To, From1, From2)
#define CHECK_P(cond, check)
#define PPL_SPECIALIZE_OUTPUT(func, Type)
The computed result is inexact and rounded up.
Definition: Result_defs.hh:84
The computed result may be inexact.
Definition: Result_defs.hh:99
#define PPL_SPECIALIZE_INPUT(func, Type)
bool round_down(Rounding_Dir dir)
#define PPL_SPECIALIZE_SMOD_2EXP(func, To, From)
bool round_not_requested(Rounding_Dir dir)
#define PPL_SPECIALIZE_MUL(func, To, From1, From2)
#define PPL_SPECIALIZE_IS_PINF(func, Type)
#define PPL_SPECIALIZE_SGN(func, From)
Result smod_2exp_mpz(mpz_class &to, const mpz_class &x, unsigned int exp, Rounding_Dir)
Result div_mpz(mpz_class &to, const mpz_class &x, const mpz_class &y, Rounding_Dir dir)