38 class Rational::Impl :
public mpq_class {
42 Impl() : mpq_class() { }
46 Impl(
const mpq_class &x) : mpq_class(x) { }
48 Impl(
const Impl &x) : mpq_class(x) { }
50 Impl(
int n,
int d) : mpq_class(n,d) { canonicalize(); }
51 Impl(
const mpz_class& n,
const mpz_class& d)
52 : mpq_class(n,d) { canonicalize(); }
54 Impl(
const string &n,
int base): mpq_class(n, base) { canonicalize(); }
55 Impl(
const string &n,
const string& d,
int base)
56 : mpq_class(n +
"/" + d, base) { canonicalize(); }
60 mpz_class getNum() {
return get_num(); }
61 mpz_class getDen() {
return get_den(); }
66 #ifdef _DEBUG_RATIONAL_
67 int &num_created = getCreated();
73 Rational::Rational(
const Rational &n) : d_n(new Impl(*n.d_n)) {
74 #ifdef _DEBUG_RATIONAL_
75 int &num_created = getCreated();
82 Rational::Rational(
const Impl& t): d_n(new Impl(t)) {
83 #ifdef _DEBUG_RATIONAL_
84 int &num_created = getCreated();
89 Rational::Rational(
int n,
int d): d_n(new Impl(n, d)) {
90 #ifdef _DEBUG_RATIONAL_
91 int &num_created = getCreated();
97 Rational::Rational(
const char* n,
int base)
98 : d_n(new Impl(string(n), base)) {
99 #ifdef _DEBUG_RATIONAL_
100 int &num_created = getCreated();
105 Rational::Rational(
const string& n,
int base)
106 : d_n(new Impl(n, base)) {
107 #ifdef _DEBUG_RATIONAL_
108 int &num_created = getCreated();
113 Rational::Rational(
const char* n,
const char* d,
int base)
114 : d_n(new Impl(string(n), string(d), base)) {
115 #ifdef _DEBUG_RATIONAL_
116 int &num_created = getCreated();
121 Rational::Rational(
const string& n,
const string& d,
int base)
122 : d_n(new Impl(n, d, base)) {
123 #ifdef _DEBUG_RATIONAL_
124 int &num_created = getCreated();
130 Rational::~Rational() {
132 #ifdef _DEBUG_RATIONAL_
133 int &num_deleted = getDeleted();
140 Rational Rational::getNumerator()
const
141 {
return Rational(Impl(d_n->getNum(), 1)); }
142 Rational Rational::getDenominator()
const
143 {
return Rational(Impl(d_n->getDen(), 1)); }
145 bool Rational::isInteger()
const {
return 1 == d_n->getDen(); }
148 Rational& Rational::operator=(
const Rational& n) {
149 if(
this == &n)
return *
this;
151 d_n =
new Impl(*n.d_n);
155 ostream &
operator<<(ostream &os,
const Rational &n) {
156 return(os << n.toString());
162 static void checkInt(
const Rational& n,
const string& funName) {
164 (
"CVC3::Rational::" + funName
165 +
": argument is not an integer: " + n.toString()).c_str());
172 Rational gcd(
const Rational &x,
const Rational &y) {
174 checkInt(x,
"gcd(*x*,y)");
175 checkInt(y,
"gcd(x,*y*)");
176 mpz_gcd(g.get_mpz_t(), x.d_n->get_num_mpz_t(), y.d_n->get_num_mpz_t());
177 return Rational(Rational::Impl(g,1));
180 Rational gcd(
const vector<Rational> &v) {
183 checkInt(v[0],
"gcd(vector<Rational>[0])");
184 g = v[0].d_n->getNum();
186 for(
unsigned i=1; i<v.size(); i++) {
187 checkInt(v[i],
"gcd(vector<Rational>)");
189 mpz_gcd(g.get_mpz_t(), g.get_mpz_t(), v[i].d_n->get_num_mpz_t());
191 return Rational(Rational::Impl(g,1));
194 Rational lcm(
const Rational &x,
const Rational &y) {
196 checkInt(x,
"lcm(*x*,y)");
197 checkInt(y,
"lcm(x,*y*)");
198 mpz_lcm(g.get_mpz_t(), x.d_n->get_num_mpz_t(), y.d_n->get_num_mpz_t());
199 return Rational(Rational::Impl(g, 1));
202 Rational lcm(
const vector<Rational> &v) {
204 for(
unsigned i=0; i<v.size(); i++) {
205 checkInt(v[i],
"lcm(vector<Rational>)");
207 mpz_lcm(g.get_mpz_t(), g.get_mpz_t(), v[i].d_n->get_num_mpz_t());
209 return Rational(Rational::Impl(g,1));
212 Rational
abs(
const Rational &x) {
213 return Rational(Rational::Impl(
abs(*x.d_n)));
216 Rational floor(
const Rational &x) {
218 mpz_fdiv_q(q.get_mpz_t(), x.d_n->get_num_mpz_t(), x.d_n->get_den_mpz_t());
219 return Rational(Rational::Impl(q,1));
222 Rational ceil(
const Rational &x) {
224 mpz_cdiv_q(q.get_mpz_t(), x.d_n->get_num_mpz_t(), x.d_n->get_den_mpz_t());
225 return Rational(Rational::Impl(q,1));
228 Rational mod(
const Rational &x,
const Rational &y) {
229 checkInt(x,
"mod(*x*,y)");
230 checkInt(y,
"mod(x,*y*)");
232 mpz_mod(r.get_mpz_t(), x.d_n->get_num_mpz_t(), y.d_n->get_num_mpz_t());
233 return(Rational(Rational::Impl(r,1)));
236 Rational intRoot(
const Rational& base,
unsigned long int n)
238 return Rational(Rational::Impl(0,1));
241 string Rational::toString(
int base)
const {
242 char *tmp = mpq_get_str(NULL, base, d_n->get_mpq_t());
249 size_t Rational::hash()
const {
251 return h(toString().c_str());
254 void Rational::print()
const {
255 cout << (*d_n) <<
endl;
262 return Rational(Rational::Impl(- (*d_n)));
265 Rational &Rational::operator+=(
const Rational &n2) {
270 Rational &Rational::operator-=(
const Rational &n2) {
275 Rational &Rational::operator*=(
const Rational &n2) {
280 Rational &Rational::operator/=(
const Rational &n2) {
285 int Rational::getInt()
const {
286 checkInt(*
this,
"getInt()");
287 return mpz_get_si(d_n->get_num_mpz_t());
290 unsigned int Rational::getUnsigned()
const {
291 checkInt(*
this,
"getUnsigned()");
292 return mpz_get_ui(d_n->get_num_mpz_t());
295 #ifdef _DEBUG_RATIONAL_
296 void Rational::printStats() {
297 int &num_created = getCreated();
298 int &num_deleted = getDeleted();
299 if(num_created % 1000 == 0 || num_deleted % 1000 == 0) {
300 std::cerr <<
"Rational(" << *d_n <<
"): created " << num_created
301 <<
", deleted " << num_deleted
302 <<
", currently alive " << num_created-num_deleted
308 bool operator==(
const Rational &n1,
const Rational &n2) {
309 return(*n1.d_n == *n2.d_n);
312 bool operator<(
const Rational &n1,
const Rational &n2) {
313 return(*n1.d_n < *n2.d_n);
316 bool operator<=(
const Rational &n1,
const Rational &n2) {
317 return(*n1.d_n <= *n2.d_n);
320 bool operator>(
const Rational &n1,
const Rational &n2) {
321 return(*n1.d_n > *n2.d_n);
324 bool operator>=(
const Rational &n1,
const Rational &n2) {
325 return(*n1.d_n >= *n2.d_n);
328 bool operator!=(
const Rational &n1,
const Rational &n2) {
329 return(*n1.d_n != *n2.d_n);
332 Rational
operator+(
const Rational &n1,
const Rational &n2) {
333 return Rational(Rational::Impl(*n1.d_n + *n2.d_n));
336 Rational
operator-(
const Rational &n1,
const Rational &n2) {
337 return Rational(Rational::Impl((*n1.d_n) - (*n2.d_n)));
340 Rational
operator*(
const Rational &n1,
const Rational &n2) {
341 return Rational(Rational::Impl((*n1.d_n) * (*n2.d_n)));
344 Rational
operator/(
const Rational &n1,
const Rational &n2) {
345 return Rational(Rational::Impl(*n1.d_n / *n2.d_n));
348 Rational operator%(
const Rational &n1,
const Rational &n2) {
349 return Rational(Rational::Impl(*n1.d_n + *n2.d_n));
354 class Unsigned::Impl :
public mpz_class {
358 Impl() : mpz_class() { }
362 Impl(
const mpz_class &x) : mpz_class(x) { }
364 Impl(
const Impl &x) : mpz_class(x) { }
366 Impl(
int n) : mpz_class(n) { }
367 Impl(
const mpz_class& n,
const mpz_class& d)
368 : mpq_class(n,d) { canonicalize(); }
370 Impl(
const string &n,
int base): mpz_class(n, base) { }
376 Unsigned::Unsigned() : d_n(new Impl) { }
378 Unsigned::Unsigned(
const Unsigned &n) : d_n(new Impl(*n.d_n)) { }
381 Unsigned::Unsigned(
const Impl& t): d_n(new Impl(t)) { }
383 Unsigned::Unsigned(
const char* n,
int base)
384 : d_n(new Impl(string(n), base)) { }
385 Unsigned::Unsigned(
const string& n,
int base)
386 : d_n(new Impl(n, base)) { }
388 Unsigned::~Unsigned() {
393 Unsigned& Unsigned::operator=(
const Unsigned& n) {
394 if(
this == &n)
return *
this;
396 d_n =
new Impl(*n.d_n);
400 ostream &
operator<<(ostream &os,
const Unsigned &n) {
401 return(os << n.toString());
409 Unsigned gcd(
const Unsigned &x,
const Unsigned &y) {
411 mpz_gcd(g, *(x.d_n), *(y.d_n));
412 return Unsigned(Unsigned::Impl(g));
415 Unsigned gcd(
const vector<Unsigned> &v) {
420 for(
unsigned i=1; i<v.size(); i++) {
422 mpz_gcd(g, g, *(v[i].d_n));
424 return Unsigned(Unsigned::Impl(g));
427 Unsigned lcm(
const Unsigned &x,
const Unsigned &y) {
429 mpz_lcm(g, *x.d_n, *y.d_n);
430 return Unsigned(Unsigned::Impl(g));
433 Unsigned lcm(
const vector<Unsigned> &v) {
435 for(
unsigned i=0; i<v.size(); i++) {
437 mpz_lcm(g, g, *v[i].d_n);
439 return Unsigned(Unsigned::Impl(g));
442 Unsigned
abs(
const Unsigned &x) {
443 return Unsigned(Unsigned::Impl(
abs(*x.d_n)));
446 Unsigned mod(
const Unsigned &x,
const Unsigned &y) {
448 mpz_mod(r, *x.d_n, *y.d_n);
449 return(Unsigned(Unsigned::Impl(r)));
452 Unsigned intRoot(
const Unsigned& base,
unsigned long int n)
454 return Unsigned(Unsigned::Impl(0,1));
457 string Unsigned::toString(
int base)
const {
458 char *tmp = mpz_get_str(NULL, base, *d_n);
465 size_t Unsigned::hash()
const {
467 return h(toString().c_str());
470 void Unsigned::print()
const {
471 cout << (*d_n) <<
endl;
478 return Unsigned(Unsigned::Impl(- (*d_n)));
481 Unsigned &Unsigned::operator+=(
const Unsigned &n2) {
486 Unsigned &Unsigned::operator-=(
const Unsigned &n2) {
491 Unsigned &Unsigned::operator*=(
const Unsigned &n2) {
496 Unsigned &Unsigned::operator/=(
const Unsigned &n2) {
501 int Unsigned::getInt()
const {
502 return mpz_get_si(*d_n);
505 unsigned int Unsigned::getUnsigned()
const {
506 return mpz_get_ui(*d_n);
509 bool operator==(
const Unsigned &n1,
const Unsigned &n2) {
510 return(*n1.d_n == *n2.d_n);
513 bool operator<(
const Unsigned &n1,
const Unsigned &n2) {
514 return(*n1.d_n < *n2.d_n);
517 bool operator<=(
const Unsigned &n1,
const Unsigned &n2) {
518 return(*n1.d_n <= *n2.d_n);
521 bool operator>(
const Unsigned &n1,
const Unsigned &n2) {
522 return(*n1.d_n > *n2.d_n);
525 bool operator>=(
const Unsigned &n1,
const Unsigned &n2) {
526 return(*n1.d_n >= *n2.d_n);
529 bool operator!=(
const Unsigned &n1,
const Unsigned &n2) {
530 return(*n1.d_n != *n2.d_n);
533 Unsigned
operator+(
const Unsigned &n1,
const Unsigned &n2) {
534 return Unsigned(Unsigned::Impl(*n1.d_n + *n2.d_n));
537 Unsigned
operator-(
const Unsigned &n1,
const Unsigned &n2) {
538 return Unsigned(Unsigned::Impl((*n1.d_n) - (*n2.d_n)));
541 Unsigned
operator*(
const Unsigned &n1,
const Unsigned &n2) {
542 return Unsigned(Unsigned::Impl((*n1.d_n) * (*n2.d_n)));
545 Unsigned
operator/(
const Unsigned &n1,
const Unsigned &n2) {
546 return Unsigned(Unsigned::Impl(*n1.d_n / *n2.d_n));
549 Unsigned operator%(
const Unsigned &n1,
const Unsigned &n2) {
550 return Unsigned(Unsigned::Impl(*n1.d_n + *n2.d_n));