00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #ifndef PPL_checked_mpz_inlines_hh
00025 #define PPL_checked_mpz_inlines_hh 1
00026
00027 #include <sstream>
00028
00029 namespace Parma_Polyhedra_Library {
00030
00031 namespace Checked {
00032
00033 template <typename Policy>
00034 inline Result
00035 round_lt_mpz(mpz_class& to, Rounding_Dir dir) {
00036 if (round_down(dir)) {
00037 --to;
00038 return V_GT;
00039 }
00040 return V_LT;
00041 }
00042
00043 template <typename Policy>
00044 inline Result
00045 round_gt_mpz(mpz_class& to, Rounding_Dir dir) {
00046 if (round_up(dir)) {
00047 ++to;
00048 return V_LT;
00049 }
00050 return V_GT;
00051 }
00052
00053 #ifdef PPL_HAVE_TYPEOF
00054
00055 typedef typeof(__mpz_struct()._mp_size) mp_size_field_t;
00056 #else
00057
00058 typedef int mp_size_field_t;
00059 #endif
00060
00061 inline mp_size_field_t
00062 get_mp_size(const mpz_class &v) {
00063 return v.get_mpz_t()->_mp_size;
00064 }
00065
00066 inline void
00067 set_mp_size(mpz_class &v, mp_size_field_t size) {
00068 v.get_mpz_t()->_mp_size = size;
00069 }
00070
00071 template <typename Policy>
00072 inline Result
00073 classify_mpz(const mpz_class& v, bool nan, bool inf, bool sign) {
00074 if (Policy::has_nan || Policy::has_infinity) {
00075 mp_size_field_t s = get_mp_size(v);
00076 if (Policy::has_nan
00077 && (nan || sign)
00078 && s == C_Integer<mp_size_field_t>::min + 1)
00079 return V_NAN;
00080 if (!inf && !sign)
00081 return V_LGE;
00082 if (Policy::has_infinity) {
00083 if (s == C_Integer<mp_size_field_t>::min)
00084 return inf ? V_EQ_MINUS_INFINITY : V_LT;
00085 if (s == C_Integer<mp_size_field_t>::max)
00086 return inf ? V_EQ_PLUS_INFINITY : V_GT;
00087 }
00088 }
00089 if (sign)
00090 return (Result) sgn<Policy>(v);
00091 return V_LGE;
00092 }
00093
00094 PPL_SPECIALIZE_CLASSIFY(classify_mpz, mpz_class)
00095
00096 template <typename Policy>
00097 inline bool
00098 is_nan_mpz(const mpz_class& v) {
00099 return Policy::has_nan
00100 && get_mp_size(v) == C_Integer<mp_size_field_t>::min + 1;
00101 }
00102
00103 PPL_SPECIALIZE_IS_NAN(is_nan_mpz, mpz_class)
00104
00105 template <typename Policy>
00106 inline bool
00107 is_minf_mpz(const mpz_class& v) {
00108 return Policy::has_infinity
00109 && get_mp_size(v) == C_Integer<mp_size_field_t>::min;
00110 }
00111
00112 PPL_SPECIALIZE_IS_MINF(is_minf_mpz, mpz_class)
00113
00114 template <typename Policy>
00115 inline bool
00116 is_pinf_mpz(const mpz_class& v) {
00117 return Policy::has_infinity
00118 && get_mp_size(v) == C_Integer<mp_size_field_t>::max;
00119 }
00120
00121 PPL_SPECIALIZE_IS_PINF(is_pinf_mpz, mpz_class)
00122
00123 template <typename Policy>
00124 inline bool
00125 is_int_mpz(const mpz_class& v) {
00126 return !is_nan<Policy>(v);
00127 }
00128
00129 PPL_SPECIALIZE_IS_INT(is_int_mpz, mpz_class)
00130
00131 template <typename Policy>
00132 inline Result
00133 assign_special_mpz(mpz_class& v, Result_Class c, Rounding_Dir) {
00134 switch (c) {
00135 case VC_NAN:
00136 if (Policy::has_nan)
00137 set_mp_size(v, C_Integer<mp_size_field_t>::min + 1);
00138 return V_NAN;
00139 case VC_MINUS_INFINITY:
00140 if (Policy::has_infinity) {
00141 set_mp_size(v, C_Integer<mp_size_field_t>::min);
00142 return V_EQ_MINUS_INFINITY;
00143 }
00144 return V_EQ_MINUS_INFINITY | V_UNREPRESENTABLE;
00145 case VC_PLUS_INFINITY:
00146 if (Policy::has_infinity) {
00147 set_mp_size(v, C_Integer<mp_size_field_t>::max);
00148 return V_EQ_PLUS_INFINITY;
00149 }
00150 return V_EQ_PLUS_INFINITY | V_UNREPRESENTABLE;
00151 default:
00152 PPL_ASSERT(false);
00153 return V_NAN;
00154 }
00155 }
00156
00157 PPL_SPECIALIZE_ASSIGN_SPECIAL(assign_special_mpz, mpz_class)
00158
00159 template <typename To_Policy, typename From_Policy>
00160 inline void
00161 copy_mpz(mpz_class& to, const mpz_class& from) {
00162 if (is_nan_mpz<From_Policy>(from))
00163 PPL_ASSERT(To_Policy::has_nan);
00164 else if (is_minf_mpz<From_Policy>(from) || is_pinf_mpz<From_Policy>(from))
00165 PPL_ASSERT(To_Policy::has_infinity);
00166 else {
00167 to = from;
00168 return;
00169 }
00170 set_mp_size(to, get_mp_size(from));
00171 }
00172
00173 PPL_SPECIALIZE_COPY(copy_mpz, mpz_class)
00174
00175 template <typename To_Policy, typename From_Policy, typename From>
00176 inline Result
00177 construct_mpz_base(mpz_class& to, const From from, Rounding_Dir) {
00178 new (&to) mpz_class(from);
00179 return V_EQ;
00180 }
00181
00182 PPL_SPECIALIZE_CONSTRUCT(construct_mpz_base, mpz_class, char)
00183 PPL_SPECIALIZE_CONSTRUCT(construct_mpz_base, mpz_class, signed char)
00184 PPL_SPECIALIZE_CONSTRUCT(construct_mpz_base, mpz_class, signed short)
00185 PPL_SPECIALIZE_CONSTRUCT(construct_mpz_base, mpz_class, signed int)
00186 PPL_SPECIALIZE_CONSTRUCT(construct_mpz_base, mpz_class, signed long)
00187 PPL_SPECIALIZE_CONSTRUCT(construct_mpz_base, mpz_class, unsigned char)
00188 PPL_SPECIALIZE_CONSTRUCT(construct_mpz_base, mpz_class, unsigned short)
00189 PPL_SPECIALIZE_CONSTRUCT(construct_mpz_base, mpz_class, unsigned int)
00190 PPL_SPECIALIZE_CONSTRUCT(construct_mpz_base, mpz_class, unsigned long)
00191
00192 template <typename To_Policy, typename From_Policy, typename From>
00193 inline Result
00194 construct_mpz_float(mpz_class& to, const From& from, Rounding_Dir dir) {
00195 if (is_nan<From_Policy>(from))
00196 return construct_special<To_Policy>(to, VC_NAN, ROUND_IGNORE);
00197 else if (is_minf<From_Policy>(from))
00198 return construct_special<To_Policy>(to, VC_MINUS_INFINITY, dir);
00199 else if (is_pinf<From_Policy>(from))
00200 return construct_special<To_Policy>(to, VC_PLUS_INFINITY, dir);
00201 if (round_not_requested(dir)) {
00202 new (&to) mpz_class(from);
00203 return V_LGE;
00204 }
00205 From n = rint(from);
00206 new (&to) mpz_class(n);
00207 if (from == n)
00208 return V_EQ;
00209 if (from < 0)
00210 return round_lt_mpz<To_Policy>(to, dir);
00211 else
00212 return round_gt_mpz<To_Policy>(to, dir);
00213 }
00214
00215 PPL_SPECIALIZE_CONSTRUCT(construct_mpz_float, mpz_class, float)
00216 PPL_SPECIALIZE_CONSTRUCT(construct_mpz_float, mpz_class, double)
00217
00218 PPL_SPECIALIZE_ASSIGN(assign_exact, mpz_class, mpz_class)
00219 PPL_SPECIALIZE_ASSIGN(assign_exact, mpz_class, char)
00220 PPL_SPECIALIZE_ASSIGN(assign_exact, mpz_class, signed char)
00221 PPL_SPECIALIZE_ASSIGN(assign_exact, mpz_class, signed short)
00222 PPL_SPECIALIZE_ASSIGN(assign_exact, mpz_class, signed int)
00223 PPL_SPECIALIZE_ASSIGN(assign_exact, mpz_class, signed long)
00224 PPL_SPECIALIZE_ASSIGN(assign_exact, mpz_class, unsigned char)
00225 PPL_SPECIALIZE_ASSIGN(assign_exact, mpz_class, unsigned short)
00226 PPL_SPECIALIZE_ASSIGN(assign_exact, mpz_class, unsigned int)
00227 PPL_SPECIALIZE_ASSIGN(assign_exact, mpz_class, unsigned long)
00228
00229 template <typename To_Policy, typename From_Policy, typename From>
00230 inline Result
00231 assign_mpz_signed_int(mpz_class& to, const From from, Rounding_Dir) {
00232 if (sizeof(From) <= sizeof(signed long))
00233 to = static_cast<signed long>(from);
00234 else {
00235 mpz_ptr m = to.get_mpz_t();
00236 if (from >= 0)
00237 mpz_import(m, 1, 1, sizeof(From), 0, 0, &from);
00238 else {
00239 From n = -from;
00240 mpz_import(m, 1, 1, sizeof(From), 0, 0, &n);
00241 mpz_neg(m, m);
00242 }
00243 }
00244 return V_EQ;
00245 }
00246
00247 PPL_SPECIALIZE_ASSIGN(assign_mpz_signed_int, mpz_class, signed long long)
00248
00249 template <typename To_Policy, typename From_Policy, typename From>
00250 inline Result
00251 assign_mpz_unsigned_int(mpz_class& to, const From from, Rounding_Dir) {
00252 if (sizeof(From) <= sizeof(unsigned long))
00253 to = static_cast<unsigned long>(from);
00254 else
00255 mpz_import(to.get_mpz_t(), 1, 1, sizeof(From), 0, 0, &from);
00256 return V_EQ;
00257 }
00258
00259 PPL_SPECIALIZE_ASSIGN(assign_mpz_unsigned_int, mpz_class, unsigned long long)
00260
00261 template <typename To_Policy, typename From_Policy, typename From>
00262 inline Result
00263 assign_mpz_float(mpz_class& to, const From from, Rounding_Dir dir) {
00264 if (is_nan<From_Policy>(from))
00265 return assign_special<To_Policy>(to, VC_NAN, ROUND_IGNORE);
00266 else if (is_minf<From_Policy>(from))
00267 return assign_special<To_Policy>(to, VC_MINUS_INFINITY, dir);
00268 else if (is_pinf<From_Policy>(from))
00269 return assign_special<To_Policy>(to, VC_PLUS_INFINITY, dir);
00270 if (round_not_requested(dir)) {
00271 to = from;
00272 return V_LGE;
00273 }
00274 From i_from = rint(from);
00275 to = i_from;
00276 if (from == i_from)
00277 return V_EQ;
00278 if (round_direct(ROUND_UP))
00279 return round_lt_mpz<To_Policy>(to, dir);
00280 if (round_direct(ROUND_DOWN))
00281 return round_gt_mpz<To_Policy>(to, dir);
00282 if (from < i_from)
00283 return round_lt_mpz<To_Policy>(to, dir);
00284 if (from > i_from)
00285 return round_gt_mpz<To_Policy>(to, dir);
00286 PPL_ASSERT(false);
00287 return V_NAN;
00288 }
00289
00290 PPL_SPECIALIZE_ASSIGN(assign_mpz_float, mpz_class, float)
00291 PPL_SPECIALIZE_ASSIGN(assign_mpz_float, mpz_class, double)
00292
00293 template <typename To_Policy, typename From_Policy, typename From>
00294 inline Result
00295 assign_mpz_long_double(mpz_class& to, const From& from, Rounding_Dir dir) {
00296 if (is_nan<From_Policy>(from))
00297 return assign_special<To_Policy>(to, VC_NAN, ROUND_IGNORE);
00298 else if (is_minf<From_Policy>(from))
00299 return assign_special<To_Policy>(to, VC_MINUS_INFINITY, dir);
00300 else if (is_pinf<From_Policy>(from))
00301 return assign_special<To_Policy>(to, VC_PLUS_INFINITY, dir);
00302
00303 std::stringstream ss;
00304 output<From_Policy>(ss, from, Numeric_Format(), dir);
00305 PPL_DIRTY_TEMP0(mpq_class, tmp);
00306 #ifndef NDEBUG
00307 Result r =
00308 #endif
00309 input_mpq(tmp, ss);
00310 PPL_ASSERT(r == V_EQ);
00311 return assign<To_Policy, From_Policy>(to, tmp, dir);
00312 }
00313
00314 PPL_SPECIALIZE_ASSIGN(assign_mpz_long_double, mpz_class, long double)
00315
00316 template <typename To_Policy, typename From_Policy>
00317 inline Result
00318 assign_mpz_mpq(mpz_class& to, const mpq_class& from, Rounding_Dir dir) {
00319 if (round_not_needed(dir)) {
00320 to = from.get_num();
00321 return V_LGE;
00322 }
00323 if (round_ignore(dir)) {
00324 to = from;
00325 return V_LGE;
00326 }
00327 mpz_srcptr n = from.get_num().get_mpz_t();
00328 mpz_srcptr d = from.get_den().get_mpz_t();
00329 if (round_down(dir)) {
00330 mpz_fdiv_q(to.get_mpz_t(), n, d);
00331 if (round_strict_relation(dir))
00332 return mpz_divisible_p(n, d) ? V_EQ : V_GT;
00333 return V_GE;
00334 }
00335 else {
00336 PPL_ASSERT(round_up(dir));
00337 mpz_cdiv_q(to.get_mpz_t(), n, d);
00338 if (round_strict_relation(dir))
00339 return mpz_divisible_p(n, d) ? V_EQ : V_LT;
00340 return V_LE;
00341 }
00342 }
00343
00344 PPL_SPECIALIZE_ASSIGN(assign_mpz_mpq, mpz_class, mpq_class)
00345
00346 PPL_SPECIALIZE_FLOOR(assign_exact, mpz_class, mpz_class)
00347 PPL_SPECIALIZE_CEIL(assign_exact, mpz_class, mpz_class)
00348 PPL_SPECIALIZE_TRUNC(assign_exact, mpz_class, mpz_class)
00349
00350 template <typename To_Policy, typename From_Policy>
00351 inline Result
00352 neg_mpz(mpz_class& to, const mpz_class& from, Rounding_Dir) {
00353 mpz_neg(to.get_mpz_t(), from.get_mpz_t());
00354 return V_EQ;
00355 }
00356
00357 PPL_SPECIALIZE_NEG(neg_mpz, mpz_class, mpz_class)
00358
00359 template <typename To_Policy, typename From1_Policy, typename From2_Policy>
00360 inline Result
00361 add_mpz(mpz_class& to, const mpz_class& x, const mpz_class& y, Rounding_Dir) {
00362 to = x + y;
00363 return V_EQ;
00364 }
00365
00366 PPL_SPECIALIZE_ADD(add_mpz, mpz_class, mpz_class, mpz_class)
00367
00368 template <typename To_Policy, typename From1_Policy, typename From2_Policy>
00369 inline Result
00370 sub_mpz(mpz_class& to, const mpz_class& x, const mpz_class& y, Rounding_Dir) {
00371 to = x - y;
00372 return V_EQ;
00373 }
00374
00375 PPL_SPECIALIZE_SUB(sub_mpz, mpz_class, mpz_class, mpz_class)
00376
00377 template <typename To_Policy, typename From1_Policy, typename From2_Policy>
00378 inline Result
00379 mul_mpz(mpz_class& to, const mpz_class& x, const mpz_class& y, Rounding_Dir) {
00380 to = x * y;
00381 return V_EQ;
00382 }
00383
00384 PPL_SPECIALIZE_MUL(mul_mpz, mpz_class, mpz_class, mpz_class)
00385
00386 template <typename To_Policy, typename From1_Policy, typename From2_Policy>
00387 inline Result
00388 div_mpz(mpz_class& to, const mpz_class& x, const mpz_class& y,
00389 Rounding_Dir dir) {
00390 if (CHECK_P(To_Policy::check_div_zero, ::sgn(y) == 0)) {
00391 return assign_nan<To_Policy>(to, V_DIV_ZERO);
00392 }
00393 mpz_srcptr n = x.get_mpz_t();
00394 mpz_srcptr d = y.get_mpz_t();
00395 if (round_not_needed(dir)) {
00396 mpz_divexact(to.get_mpz_t(), n, d);
00397 return V_LGE;
00398 }
00399 if (round_ignore(dir)) {
00400 mpz_cdiv_q(to.get_mpz_t(), n, d);
00401 return V_LE;
00402 }
00403 if (round_down(dir)) {
00404 mpz_fdiv_q(to.get_mpz_t(), n, d);
00405 if (round_strict_relation(dir))
00406 return mpz_divisible_p(n, d) ? V_EQ : V_GT;
00407 return V_GE;
00408 }
00409 else {
00410 PPL_ASSERT(round_up(dir));
00411 mpz_cdiv_q(to.get_mpz_t(), n, d);
00412 if (round_strict_relation(dir))
00413 return mpz_divisible_p(n, d) ? V_EQ : V_LT;
00414 return V_LE;
00415 }
00416 }
00417
00418 PPL_SPECIALIZE_DIV(div_mpz, mpz_class, mpz_class, mpz_class)
00419
00420 template <typename To_Policy, typename From1_Policy, typename From2_Policy>
00421 inline Result
00422 idiv_mpz(mpz_class& to, const mpz_class& x, const mpz_class& y,
00423 Rounding_Dir) {
00424 if (CHECK_P(To_Policy::check_div_zero, ::sgn(y) == 0)) {
00425 return assign_nan<To_Policy>(to, V_DIV_ZERO);
00426 }
00427 mpz_srcptr n = x.get_mpz_t();
00428 mpz_srcptr d = y.get_mpz_t();
00429 mpz_tdiv_q(to.get_mpz_t(), n, d);
00430 return V_EQ;
00431 }
00432
00433 PPL_SPECIALIZE_IDIV(idiv_mpz, mpz_class, mpz_class, mpz_class)
00434
00435 template <typename To_Policy, typename From1_Policy, typename From2_Policy>
00436 inline Result
00437 rem_mpz(mpz_class& to, const mpz_class& x, const mpz_class& y, Rounding_Dir) {
00438 if (CHECK_P(To_Policy::check_div_zero, ::sgn(y) == 0)) {
00439 return assign_nan<To_Policy>(to, V_MOD_ZERO);
00440 }
00441 to = x % y;
00442 return V_EQ;
00443 }
00444
00445 PPL_SPECIALIZE_REM(rem_mpz, mpz_class, mpz_class, mpz_class)
00446
00447 template <typename To_Policy, typename From_Policy>
00448 inline Result
00449 add_2exp_mpz(mpz_class& to, const mpz_class& x, unsigned int exp,
00450 Rounding_Dir) {
00451 PPL_DIRTY_TEMP(mpz_class, v);
00452 v = 1;
00453 mpz_mul_2exp(v.get_mpz_t(), v.get_mpz_t(), exp);
00454 to = x + v;
00455 return V_EQ;
00456 }
00457
00458 PPL_SPECIALIZE_ADD_2EXP(add_2exp_mpz, mpz_class, mpz_class)
00459
00460 template <typename To_Policy, typename From_Policy>
00461 inline Result
00462 sub_2exp_mpz(mpz_class& to, const mpz_class& x, unsigned int exp,
00463 Rounding_Dir) {
00464 PPL_DIRTY_TEMP(mpz_class, v);
00465 v = 1;
00466 mpz_mul_2exp(v.get_mpz_t(), v.get_mpz_t(), exp);
00467 to = x - v;
00468 return V_EQ;
00469 }
00470
00471 PPL_SPECIALIZE_SUB_2EXP(sub_2exp_mpz, mpz_class, mpz_class)
00472
00473 template <typename To_Policy, typename From_Policy>
00474 inline Result
00475 mul_2exp_mpz(mpz_class& to, const mpz_class& x, unsigned int exp,
00476 Rounding_Dir) {
00477 mpz_mul_2exp(to.get_mpz_t(), x.get_mpz_t(), exp);
00478 return V_EQ;
00479 }
00480
00481 PPL_SPECIALIZE_MUL_2EXP(mul_2exp_mpz, mpz_class, mpz_class)
00482
00483 template <typename To_Policy, typename From_Policy>
00484 inline Result
00485 div_2exp_mpz(mpz_class& to, const mpz_class& x, unsigned int exp,
00486 Rounding_Dir dir) {
00487 mpz_srcptr n = x.get_mpz_t();
00488 if (round_not_requested(dir)) {
00489 mpz_tdiv_q_2exp(to.get_mpz_t(), x.get_mpz_t(), exp);
00490 return V_LGE;
00491 }
00492 if (round_down(dir)) {
00493 mpz_fdiv_q_2exp(to.get_mpz_t(), n, exp);
00494 if (round_strict_relation(dir))
00495 return mpz_divisible_2exp_p(n, exp) ? V_EQ : V_GT;
00496 return V_GE;
00497 }
00498 else {
00499 PPL_ASSERT(round_up(dir));
00500 mpz_cdiv_q_2exp(to.get_mpz_t(), n, exp);
00501 if (round_strict_relation(dir))
00502 return mpz_divisible_2exp_p(n, exp) ? V_EQ : V_LT;
00503 return V_LE;
00504 }
00505 }
00506
00507 PPL_SPECIALIZE_DIV_2EXP(div_2exp_mpz, mpz_class, mpz_class)
00508
00509 template <typename To_Policy, typename From_Policy>
00510 inline Result
00511 smod_2exp_mpz(mpz_class& to, const mpz_class& x, unsigned int exp,
00512 Rounding_Dir) {
00513 if (mpz_tstbit(x.get_mpz_t(), exp - 1))
00514 mpz_cdiv_r_2exp(to.get_mpz_t(), x.get_mpz_t(), exp);
00515 else
00516 mpz_fdiv_r_2exp(to.get_mpz_t(), x.get_mpz_t(), exp);
00517 return V_EQ;
00518 }
00519
00520 PPL_SPECIALIZE_SMOD_2EXP(smod_2exp_mpz, mpz_class, mpz_class)
00521
00522 template <typename To_Policy, typename From_Policy>
00523 inline Result
00524 umod_2exp_mpz(mpz_class& to, const mpz_class& x, unsigned int exp,
00525 Rounding_Dir) {
00526 mpz_fdiv_r_2exp(to.get_mpz_t(), x.get_mpz_t(), exp);
00527 return V_EQ;
00528 }
00529
00530 PPL_SPECIALIZE_UMOD_2EXP(umod_2exp_mpz, mpz_class, mpz_class)
00531
00532 template <typename To_Policy, typename From_Policy>
00533 inline Result
00534 abs_mpz(mpz_class& to, const mpz_class& from, Rounding_Dir) {
00535 to = abs(from);
00536 return V_EQ;
00537 }
00538
00539 PPL_SPECIALIZE_ABS(abs_mpz, mpz_class, mpz_class)
00540
00541 template <typename To_Policy, typename From1_Policy, typename From2_Policy>
00542 inline Result
00543 add_mul_mpz(mpz_class& to, const mpz_class& x, const mpz_class& y,
00544 Rounding_Dir) {
00545 mpz_addmul(to.get_mpz_t(), x.get_mpz_t(), y.get_mpz_t());
00546 return V_EQ;
00547 }
00548
00549 PPL_SPECIALIZE_ADD_MUL(add_mul_mpz, mpz_class, mpz_class, mpz_class)
00550
00551 template <typename To_Policy, typename From1_Policy, typename From2_Policy>
00552 inline Result
00553 sub_mul_mpz(mpz_class& to, const mpz_class& x, const mpz_class& y,
00554 Rounding_Dir) {
00555 mpz_submul(to.get_mpz_t(), x.get_mpz_t(), y.get_mpz_t());
00556 return V_EQ;
00557 }
00558
00559 PPL_SPECIALIZE_SUB_MUL(sub_mul_mpz, mpz_class, mpz_class, mpz_class)
00560
00561 template <typename To_Policy, typename From1_Policy, typename From2_Policy>
00562 inline Result
00563 gcd_mpz(mpz_class& to, const mpz_class& x, const mpz_class& y, Rounding_Dir) {
00564 mpz_gcd(to.get_mpz_t(), x.get_mpz_t(), y.get_mpz_t());
00565 return V_EQ;
00566 }
00567
00568 PPL_SPECIALIZE_GCD(gcd_mpz, mpz_class, mpz_class, mpz_class)
00569
00570 template <typename To_Policy, typename From1_Policy, typename From2_Policy>
00571 inline Result
00572 gcdext_mpz(mpz_class& to, mpz_class& s, mpz_class& t,
00573 const mpz_class& x, const mpz_class& y,
00574 Rounding_Dir) {
00575 mpz_gcdext(to.get_mpz_t(), s.get_mpz_t(), t.get_mpz_t(),
00576 x.get_mpz_t(), y.get_mpz_t());
00577 return V_EQ;
00578 }
00579
00580 PPL_SPECIALIZE_GCDEXT(gcdext_mpz, mpz_class, mpz_class, mpz_class, mpz_class, mpz_class)
00581
00582 template <typename To_Policy, typename From1_Policy, typename From2_Policy>
00583 inline Result
00584 lcm_mpz(mpz_class& to, const mpz_class& x, const mpz_class& y, Rounding_Dir) {
00585 mpz_lcm(to.get_mpz_t(), x.get_mpz_t(), y.get_mpz_t());
00586 return V_EQ;
00587 }
00588
00589 PPL_SPECIALIZE_LCM(lcm_mpz, mpz_class, mpz_class, mpz_class)
00590
00591 template <typename To_Policy, typename From_Policy>
00592 inline Result
00593 sqrt_mpz(mpz_class& to, const mpz_class& from, Rounding_Dir dir) {
00594 if (CHECK_P(To_Policy::check_sqrt_neg, from < 0)) {
00595 return assign_nan<To_Policy>(to, V_SQRT_NEG);
00596 }
00597 if (round_not_requested(dir)) {
00598 to = sqrt(from);
00599 return V_GE;
00600 }
00601 PPL_DIRTY_TEMP0(mpz_class, r);
00602 mpz_sqrtrem(to.get_mpz_t(), r.get_mpz_t(), from.get_mpz_t());
00603 if (r == 0)
00604 return V_EQ;
00605 return round_gt_mpz<To_Policy>(to, dir);
00606 }
00607
00608 PPL_SPECIALIZE_SQRT(sqrt_mpz, mpz_class, mpz_class)
00609
00610 template <typename Policy, typename Type>
00611 inline Result_Relation
00612 sgn_mp(const Type& x) {
00613 int i = ::sgn(x);
00614 return i > 0 ? VR_GT : i < 0 ? VR_LT : VR_EQ;
00615 }
00616
00617 PPL_SPECIALIZE_SGN(sgn_mp, mpz_class)
00618 PPL_SPECIALIZE_SGN(sgn_mp, mpq_class)
00619
00620 template <typename Policy1, typename Policy2, typename Type>
00621 inline Result_Relation
00622 cmp_mp(const Type& x, const Type& y) {
00623 int i = ::cmp(x, y);
00624 return i > 0 ? VR_GT : i < 0 ? VR_LT : VR_EQ;
00625 }
00626
00627 PPL_SPECIALIZE_CMP(cmp_mp, mpz_class, mpz_class)
00628 PPL_SPECIALIZE_CMP(cmp_mp, mpq_class, mpq_class)
00629
00630 template <typename Policy>
00631 inline Result
00632 output_mpz(std::ostream& os, const mpz_class& from, const Numeric_Format&,
00633 Rounding_Dir) {
00634 os << from;
00635 return V_EQ;
00636 }
00637
00638 PPL_SPECIALIZE_INPUT(input_generic, mpz_class)
00639 PPL_SPECIALIZE_OUTPUT(output_mpz, mpz_class)
00640
00641 }
00642
00643 }
00644
00645 #endif // !defined(PPL_checked_mpz_inlines_hh)