35 #ifdef SOPLEX_WITH_GMP 40 #define SOPLEX_PERFALT_1 43 #define SOPLEX_PERFALT_2a 46 #define SOPLEX_PERFALT_2b 49 #define SOPLEX_PERFALT_3 52 #define SOPLEX_PERFALT_4 55 #define SOPLEX_PERFALT_5a 58 #define SOPLEX_PERFALT_5b 63 #ifdef SOPLEX_WITH_GMP 66 const Rational Rational::ZERO(0,
true);
69 const Rational Rational::POSONE(1,
true);
72 const Rational Rational::NEGONE(-1,
true);
77 #ifdef SOPLEX_NOLISTMEM 88 #ifdef SOPLEX_WITH_GMP 89 THREADLOCAL IdList< Rational::Private > Rational::unusedPrivateList(0, 0,
true);
93 class Rational::Private
106 mpq_init(privatevalue);
116 mpq_init(privatevalue);
117 mpq_set(this->privatevalue, p.privatevalue);
125 mpq_init(privatevalue);
126 if( r == (
long double)(1.0) )
128 else if( r == (
long double)(-1.0) )
130 else if( r == (
long double)(0.0) )
135 mpq_set_d(privatevalue,
double(r));
143 mpq_init(privatevalue);
153 mpq_set_d(privatevalue, r);
161 mpq_init(privatevalue);
171 mpq_set_si(privatevalue, i, 1);
179 mpq_init(privatevalue);
180 mpq_set(privatevalue, q);
186 mpq_clear(privatevalue);
192 #ifdef SOPLEX_PERFALT_4 193 if( mpq_equal(this->privatevalue, p.privatevalue) != 0 )
198 mpq_set(this->privatevalue, p.privatevalue);
206 if( r == (
long double)(0.0) )
208 #ifdef SOPLEX_PERFALT_5a 209 #ifdef SOPLEX_PERFALT_1 210 if( mpq_sgn(privatevalue) != 0 )
217 else if( r == (
long double)(1.0) )
219 #ifdef SOPLEX_PERFALT_5b 224 else if( r == (
long double)(-1.0) )
226 #ifdef SOPLEX_PERFALT_5b 232 mpq_set_d(this->privatevalue,
double(r));
243 #ifdef SOPLEX_PERFALT_5a 244 #ifdef SOPLEX_PERFALT_1 245 if( mpq_sgn(privatevalue) != 0 )
254 #ifdef SOPLEX_PERFALT_5b 261 #ifdef SOPLEX_PERFALT_5b 267 mpq_set_d(privatevalue, r);
278 #ifdef SOPLEX_PERFALT_5a 279 #ifdef SOPLEX_PERFALT_1 280 if( mpq_sgn(privatevalue) != 0 )
289 #ifdef SOPLEX_PERFALT_5b 296 #ifdef SOPLEX_PERFALT_5b 302 mpq_set_si(privatevalue, i, 1);
310 #ifdef SOPLEX_PERFALT_4 311 if( mpq_equal(this->privatevalue, q) != 0 )
316 mpq_set(this->privatevalue, q);
364 if( Rational::useListMem )
366 dpointer = unusedPrivateList.last();
370 assert(unusedPrivateList.first() != 0);
375 assert(unusedPrivateList.first() == 0);
382 assert(unusedPrivateList.length() == 0);
396 if( Rational::useListMem )
398 dpointer = unusedPrivateList.last();
402 assert(unusedPrivateList.first() != 0);
408 assert(unusedPrivateList.first() == 0);
415 assert(unusedPrivateList.length() == 0);
429 if( Rational::useListMem )
431 dpointer = unusedPrivateList.last();
435 assert(unusedPrivateList.first() != 0);
441 assert(unusedPrivateList.first() == 0);
448 assert(unusedPrivateList.length() == 0);
462 if( Rational::useListMem )
464 dpointer = unusedPrivateList.last();
468 assert(unusedPrivateList.first() != 0);
474 assert(unusedPrivateList.first() == 0);
481 assert(unusedPrivateList.length() == 0);
495 if( Rational::useListMem )
497 dpointer = unusedPrivateList.last();
501 assert(unusedPrivateList.first() != 0);
507 assert(unusedPrivateList.first() == 0);
514 assert(unusedPrivateList.length() == 0);
528 if( Rational::useListMem )
530 dpointer = unusedPrivateList.last();
534 assert(unusedPrivateList.first() != 0);
540 assert(unusedPrivateList.first() == 0);
547 assert(unusedPrivateList.length() == 0);
561 assert(Rational::useListMem || unusedPrivateList.length() == 0);
563 if( !Rational::useListMem ||
this == &Rational::ZERO ||
this == &Rational::POSONE ||
this == &Rational::NEGONE )
583 assert(Rational::useListMem || unusedPrivateList.length() == 0);
584 Rational::useListMem =
true;
597 unusedPrivateList.clear(
true);
598 assert(unusedPrivateList.length() == 0);
607 Rational::useListMem =
false;
658 Rational::operator double()
const 660 #ifdef SOPLEX_PERFALT_3 661 #ifdef SOPLEX_PERFALT_1 667 else if( mpq_equal(this->
dpointer->
privatevalue, Rational::POSONE.dpointer->privatevalue) != 0 )
669 else if( mpq_equal(this->
dpointer->
privatevalue, Rational::NEGONE.dpointer->privatevalue) != 0 )
679 Rational::operator
long double()
const 681 #ifdef SOPLEX_PERFALT_3 682 #ifdef SOPLEX_PERFALT_1 688 else if( mpq_equal(this->
dpointer->
privatevalue, Rational::POSONE.dpointer->privatevalue) != 0 )
690 else if( mpq_equal(this->
dpointer->
privatevalue, Rational::NEGONE.dpointer->privatevalue) != 0 )
700 const mpq_t* Rational::getMpqPtr()
const 708 const mpq_t& Rational::getMpqRef()
const 716 mpq_t* Rational::getMpqPtr_w()
const 724 mpq_t& Rational::getMpqRef_w()
const 734 #ifdef SOPLEX_PERFALT_2a 735 #ifdef SOPLEX_PERFALT_1 736 if( mpq_sgn(r.dpointer->privatevalue) == 0 )
741 if( mpq_equal(r.dpointer->privatevalue, Rational::ZERO.dpointer->privatevalue) != 0 )
749 mpq_add(retval.dpointer->privatevalue, this->dpointer->privatevalue, r.dpointer->privatevalue);
758 #ifdef SOPLEX_PERFALT_2a 759 #ifdef SOPLEX_PERFALT_1 760 if( mpq_sgn(r.dpointer->privatevalue) == 0 )
765 if( mpq_equal(r.dpointer->privatevalue, Rational::ZERO.dpointer->privatevalue) != 0 )
785 #ifdef SOPLEX_PERFALT_2a 786 #ifdef SOPLEX_PERFALT_1 796 mpq_add(retval.dpointer->privatevalue, this->dpointer->privatevalue, retval.dpointer->privatevalue);
807 return (*
this += Rational::POSONE);
809 return (*
this += Rational::NEGONE);
812 #ifdef SOPLEX_PERFALT_2a 813 #ifdef SOPLEX_PERFALT_1 823 mpq_add(this->
dpointer->
privatevalue, this->dpointer->privatevalue, retval.dpointer->privatevalue);
838 #ifdef SOPLEX_PERFALT_2a 839 #ifdef SOPLEX_PERFALT_1 849 mpq_add(retval.dpointer->privatevalue, this->dpointer->privatevalue, retval.dpointer->privatevalue);
860 return (*
this += Rational::POSONE);
862 return (*
this += Rational::NEGONE);
865 #ifdef SOPLEX_PERFALT_2a 866 #ifdef SOPLEX_PERFALT_1 876 mpq_add(this->
dpointer->
privatevalue, this->dpointer->privatevalue, retval.dpointer->privatevalue);
887 #ifdef SOPLEX_PERFALT_2a 888 #ifdef SOPLEX_PERFALT_1 889 if( mpq_sgn(r.dpointer->privatevalue) == 0 )
894 if( mpq_equal(r.dpointer->privatevalue, Rational::ZERO.dpointer->privatevalue) != 0 )
902 mpq_sub(retval.dpointer->privatevalue, this->dpointer->privatevalue, r.dpointer->privatevalue);
911 #ifdef SOPLEX_PERFALT_2a 912 #ifdef SOPLEX_PERFALT_1 913 if( mpq_sgn(r.dpointer->privatevalue) == 0 )
922 if( mpq_equal(r.dpointer->privatevalue, Rational::ZERO.dpointer->privatevalue) != 0 )
946 #ifdef SOPLEX_PERFALT_2a 947 #ifdef SOPLEX_PERFALT_1 957 mpq_sub(retval.dpointer->privatevalue, this->dpointer->privatevalue, retval.dpointer->privatevalue);
969 return (*
this -= Rational::POSONE);
971 return (*
this -= Rational::NEGONE);
974 #ifdef SOPLEX_PERFALT_2a 975 #ifdef SOPLEX_PERFALT_1 985 mpq_sub(this->
dpointer->
privatevalue, this->dpointer->privatevalue, retval.dpointer->privatevalue);
1000 #ifdef SOPLEX_PERFALT_2a 1001 #ifdef SOPLEX_PERFALT_1 1011 mpq_sub(retval.dpointer->privatevalue, this->dpointer->privatevalue, retval.dpointer->privatevalue);
1023 return (*
this -= Rational::POSONE);
1025 return (*
this -= Rational::NEGONE);
1028 #ifdef SOPLEX_PERFALT_2a 1029 #ifdef SOPLEX_PERFALT_1 1031 return (*
this = -d);
1034 return (*
this = -d);
1039 mpq_sub(this->
dpointer->
privatevalue, this->dpointer->privatevalue, retval.dpointer->privatevalue);
1050 #ifdef SOPLEX_PERFALT_2b 1051 #ifdef SOPLEX_PERFALT_1 1052 if( mpq_sgn(r.dpointer->privatevalue) == 0 )
1053 return Rational::ZERO;
1055 return Rational::ZERO;
1057 if( mpq_equal(r.dpointer->privatevalue, Rational::ZERO.dpointer->privatevalue) != 0 )
1058 return Rational::ZERO;
1060 return Rational::ZERO;
1062 else if( mpq_equal(r.dpointer->privatevalue, Rational::POSONE.dpointer->privatevalue) != 0 )
1064 else if( mpq_equal(this->
dpointer->
privatevalue, Rational::POSONE.dpointer->privatevalue) != 0 )
1066 else if( mpq_equal(r.dpointer->privatevalue, Rational::NEGONE.dpointer->privatevalue) != 0 )
1068 else if( mpq_equal(this->
dpointer->
privatevalue, Rational::NEGONE.dpointer->privatevalue) != 0 )
1073 mpq_mul(retval.dpointer->privatevalue, this->dpointer->privatevalue, r.dpointer->privatevalue);
1082 #ifdef SOPLEX_PERFALT_2b 1083 #ifdef SOPLEX_PERFALT_1 1084 if( mpq_sgn(r.dpointer->privatevalue) == 0 )
1085 return (*
this = Rational::ZERO);
1089 if( mpq_equal(r.dpointer->privatevalue, Rational::ZERO.dpointer->privatevalue) != 0 )
1090 return (*
this = Rational::ZERO);
1094 else if( mpq_equal(r.dpointer->privatevalue, Rational::POSONE.dpointer->privatevalue) != 0 )
1096 else if( mpq_equal(this->
dpointer->
privatevalue, Rational::POSONE.dpointer->privatevalue) != 0 )
1098 else if( mpq_equal(r.dpointer->privatevalue, Rational::NEGONE.dpointer->privatevalue) != 0 )
1103 else if( mpq_equal(this->
dpointer->
privatevalue, Rational::NEGONE.dpointer->privatevalue) != 0 )
1120 return Rational::ZERO;
1123 else if( d == -1.0 )
1126 mpq_neg(retval.dpointer->privatevalue, this->dpointer->privatevalue);
1131 #ifdef SOPLEX_PERFALT_2b 1132 #ifdef SOPLEX_PERFALT_1 1134 return Rational::ZERO;
1137 return Rational::ZERO;
1139 else if( mpq_equal(this->
dpointer->
privatevalue, Rational::POSONE.dpointer->privatevalue) != 0 )
1141 else if( mpq_equal(this->
dpointer->
privatevalue, Rational::NEGONE.dpointer->privatevalue) != 0 )
1146 mpq_mul(retval.dpointer->privatevalue, retval.dpointer->privatevalue, this->dpointer->privatevalue);
1157 return (*
this = Rational::ZERO);
1160 else if( d == -1.0 )
1167 #ifdef SOPLEX_PERFALT_2b 1168 #ifdef SOPLEX_PERFALT_1 1175 else if( mpq_equal(this->
dpointer->
privatevalue, Rational::POSONE.dpointer->privatevalue) != 0 )
1177 else if( mpq_equal(this->
dpointer->
privatevalue, Rational::NEGONE.dpointer->privatevalue) != 0 )
1186 mpq_mul(this->
dpointer->
privatevalue, this->dpointer->privatevalue, retval.dpointer->privatevalue);
1197 return Rational::ZERO;
1203 mpq_neg(retval.dpointer->privatevalue, this->dpointer->privatevalue);
1208 #ifdef SOPLEX_PERFALT_2b 1209 #ifdef SOPLEX_PERFALT_1 1211 return Rational::ZERO;
1214 return Rational::ZERO;
1216 else if( mpq_equal(this->
dpointer->
privatevalue, Rational::POSONE.dpointer->privatevalue) != 0 )
1218 else if( mpq_equal(this->
dpointer->
privatevalue, Rational::NEGONE.dpointer->privatevalue) != 0 )
1223 mpq_mul(retval.dpointer->privatevalue, retval.dpointer->privatevalue, this->dpointer->privatevalue);
1234 return (*
this = Rational::ZERO);
1244 #ifdef SOPLEX_PERFALT_2b 1245 #ifdef SOPLEX_PERFALT_1 1252 else if( mpq_equal(this->
dpointer->
privatevalue, Rational::POSONE.dpointer->privatevalue) != 0 )
1254 else if( mpq_equal(this->
dpointer->
privatevalue, Rational::NEGONE.dpointer->privatevalue) != 0 )
1263 mpq_mul(this->
dpointer->
privatevalue, this->dpointer->privatevalue, retval.dpointer->privatevalue);
1273 #ifdef SOPLEX_PERFALT_2b 1274 #ifdef SOPLEX_PERFALT_1 1276 return Rational::ZERO;
1279 return Rational::ZERO;
1281 else if( mpq_equal(r.dpointer->privatevalue, Rational::POSONE.dpointer->privatevalue) != 0 )
1283 else if( mpq_equal(this->
dpointer->
privatevalue, Rational::POSONE.dpointer->privatevalue) != 0 )
1289 else if( mpq_equal(r.dpointer->privatevalue, Rational::NEGONE.dpointer->privatevalue) != 0 )
1291 else if( mpq_equal(this->
dpointer->
privatevalue, Rational::NEGONE.dpointer->privatevalue) != 0 )
1295 mpq_neg(retval.dpointer->privatevalue, retval.dpointer->privatevalue);
1301 mpq_div(retval.dpointer->privatevalue, this->dpointer->privatevalue, r.dpointer->privatevalue);
1310 #ifdef SOPLEX_PERFALT_2b 1311 #ifdef SOPLEX_PERFALT_1 1318 else if( mpq_equal(r.dpointer->privatevalue, Rational::POSONE.dpointer->privatevalue) != 0 )
1320 else if( mpq_equal(r.dpointer->privatevalue, Rational::NEGONE.dpointer->privatevalue) != 0 )
1325 else if( mpq_equal(this->
dpointer->
privatevalue, Rational::POSONE.dpointer->privatevalue) != 0 )
1330 else if( mpq_equal(this->
dpointer->
privatevalue, Rational::NEGONE.dpointer->privatevalue) != 0 )
1349 else if( d == -1.0 )
1353 #ifdef SOPLEX_PERFALT_2b 1354 #ifdef SOPLEX_PERFALT_1 1356 return Rational::ZERO;
1359 return Rational::ZERO;
1361 else if( mpq_equal(this->
dpointer->
privatevalue, Rational::POSONE.dpointer->privatevalue) != 0 )
1367 else if( mpq_equal(this->
dpointer->
privatevalue, Rational::NEGONE.dpointer->privatevalue) != 0 )
1371 mpq_neg(retval.dpointer->privatevalue, retval.dpointer->privatevalue);
1377 mpq_div(retval.dpointer->privatevalue, this->dpointer->privatevalue, retval.dpointer->privatevalue);
1389 else if( d == -1.0 )
1396 #ifdef SOPLEX_PERFALT_2b 1397 #ifdef SOPLEX_PERFALT_1 1404 else if( mpq_equal(this->
dpointer->
privatevalue, Rational::POSONE.dpointer->privatevalue) != 0 )
1410 else if( mpq_equal(this->
dpointer->
privatevalue, Rational::NEGONE.dpointer->privatevalue) != 0 )
1419 mpq_div(this->
dpointer->
privatevalue, this->dpointer->privatevalue, retval.dpointer->privatevalue);
1435 #ifdef SOPLEX_PERFALT_2b 1436 #ifdef SOPLEX_PERFALT_1 1438 return Rational::ZERO;
1441 return Rational::ZERO;
1443 else if( mpq_equal(this->
dpointer->
privatevalue, Rational::POSONE.dpointer->privatevalue) != 0 )
1449 else if( mpq_equal(this->
dpointer->
privatevalue, Rational::NEGONE.dpointer->privatevalue) != 0 )
1453 mpq_neg(retval.dpointer->privatevalue, retval.dpointer->privatevalue);
1459 mpq_div(retval.dpointer->privatevalue, this->dpointer->privatevalue, retval.dpointer->privatevalue);
1478 #ifdef SOPLEX_PERFALT_2b 1479 #ifdef SOPLEX_PERFALT_1 1486 else if( mpq_equal(this->
dpointer->
privatevalue, Rational::POSONE.dpointer->privatevalue) != 0 )
1492 else if( mpq_equal(this->
dpointer->
privatevalue, Rational::NEGONE.dpointer->privatevalue) != 0 )
1501 mpq_div(this->
dpointer->
privatevalue, this->dpointer->privatevalue, retval.dpointer->privatevalue);
1511 #ifdef SOPLEX_PERFALT_2b 1512 if( mpq_equal(r.dpointer->privatevalue, Rational::POSONE.dpointer->privatevalue) != 0 )
1517 else if( mpq_equal(s.dpointer->privatevalue, Rational::POSONE.dpointer->privatevalue) != 0 )
1522 else if( mpq_equal(r.dpointer->privatevalue, Rational::NEGONE.dpointer->privatevalue) != 0 )
1527 else if( mpq_equal(s.dpointer->privatevalue, Rational::NEGONE.dpointer->privatevalue) != 0 )
1532 #if 0 // currently, SoPlex calls this method only with nonzero r and s, hence we do not check this case 1533 #ifdef SOPLEX_PERFALT_1 1534 else if( mpq_sgn(r.dpointer->privatevalue) == 0 )
1536 else if( mpq_sgn(s.dpointer->privatevalue) == 0 )
1539 else if( mpq_equal(r.dpointer->privatevalue, Rational::ZERO.dpointer->privatevalue) != 0 )
1541 else if( mpq_equal(s.dpointer->privatevalue, Rational::ZERO.dpointer->privatevalue) != 0 )
1548 mpq_mul(product.dpointer->privatevalue, product.dpointer->privatevalue, s.dpointer->privatevalue);
1549 mpq_add(this->
dpointer->
privatevalue, this->dpointer->privatevalue, product.dpointer->privatevalue);
1558 #ifdef SOPLEX_PERFALT_2b 1559 if( mpq_equal(r.dpointer->privatevalue, Rational::POSONE.dpointer->privatevalue) != 0 )
1564 else if( mpq_equal(s.dpointer->privatevalue, Rational::POSONE.dpointer->privatevalue) != 0 )
1569 else if( mpq_equal(r.dpointer->privatevalue, Rational::NEGONE.dpointer->privatevalue) != 0 )
1574 else if( mpq_equal(s.dpointer->privatevalue, Rational::NEGONE.dpointer->privatevalue) != 0 )
1579 #if 0 // currently, SoPlex calls this method only with nonzero r and s, hence we do not check this case 1580 #ifdef SOPLEX_PERFALT_1 1581 if( mpq_sgn(r.dpointer->privatevalue) == 0 )
1583 else if( mpq_sgn(s.dpointer->privatevalue) == 0 )
1586 if( mpq_equal(r.dpointer->privatevalue, Rational::ZERO.dpointer->privatevalue) != 0 )
1588 else if( mpq_equal(s.dpointer->privatevalue, Rational::ZERO.dpointer->privatevalue) != 0 )
1595 mpq_mul(product.dpointer->privatevalue, product.dpointer->privatevalue, s.dpointer->privatevalue);
1596 mpq_sub(this->
dpointer->
privatevalue, this->dpointer->privatevalue, product.dpointer->privatevalue);
1605 #ifdef SOPLEX_PERFALT_2b 1606 #ifdef SOPLEX_PERFALT_1 1607 if( mpq_sgn(r.dpointer->privatevalue) == 0 )
1610 if( mpq_equal(r.dpointer->privatevalue, Rational::ZERO.dpointer->privatevalue) != 0 )
1613 else if( mpq_equal(s.dpointer->privatevalue, Rational::POSONE.dpointer->privatevalue) != 0 )
1618 else if( mpq_equal(s.dpointer->privatevalue, Rational::NEGONE.dpointer->privatevalue) != 0 )
1626 mpq_div(quotient.dpointer->privatevalue, quotient.dpointer->privatevalue, s.dpointer->privatevalue);
1627 mpq_add(this->
dpointer->
privatevalue, this->dpointer->privatevalue, quotient.dpointer->privatevalue);
1636 #ifdef SOPLEX_PERFALT_2b 1637 #ifdef SOPLEX_PERFALT_1 1638 if( mpq_sgn(r.dpointer->privatevalue) == 0 )
1641 if( mpq_equal(r.dpointer->privatevalue, Rational::ZERO.dpointer->privatevalue) != 0 )
1644 else if( mpq_equal(s.dpointer->privatevalue, Rational::POSONE.dpointer->privatevalue) != 0 )
1649 else if( mpq_equal(s.dpointer->privatevalue, Rational::NEGONE.dpointer->privatevalue) != 0 )
1657 mpq_div(quotient.dpointer->privatevalue, quotient.dpointer->privatevalue, s.dpointer->privatevalue);
1658 mpq_sub(this->
dpointer->
privatevalue, this->dpointer->privatevalue, quotient.dpointer->privatevalue);
1682 mpz_sub_ui(roundval, roundval, 1);
1684 MSG_DEBUG( std::cout <<
" --> " << mpz_get_str(0, 10, roundval) <<
"\n" );
1686 size_t binlog = mpz_sizeinbase(roundval, 2);
1688 MSG_DEBUG( std::cout <<
" --> 2^" << binlog <<
"\n" );
1690 mpz_ui_pow_ui(roundval, 2, binlog);
1692 MSG_DEBUG( std::cout <<
" --> " << mpz_get_str(0, 10, roundval) <<
"\n" );
1695 mpz_clear(roundval);
1763 return ((a == d) || (b == d));
1785 #define MAX_STR_LEN 10000 1790 assert(strlen(s) <= MAX_STR_LEN);
1796 if( strchr(s,
'/') != 0 || strpbrk(s,
".eE") == 0 )
1798 pos = (*s ==
'+') ? s + 1 : s;
1799 if( mpq_set_str(value.dpointer->privatevalue, pos, 10) == 0 )
1801 mpq_canonicalize(value.dpointer->privatevalue);
1811 bool has_exponent =
false;
1812 bool has_dot =
false;
1814 bool has_digits =
false;
1815 bool has_emptyexponent =
false;
1816 long int exponent = 0;
1817 long int decshift = 0;
1819 mpz_init(shiftpower);
1820 mpq_t shiftpowerRational;
1821 mpq_init(shiftpowerRational);
1823 char tmp[MAX_STR_LEN];
1828 if( (*pos ==
'+') || (*pos ==
'-') )
1832 while( (*pos >=
'0') && (*pos <=
'9') )
1847 while( (*pos >=
'0') && (*pos <=
'9') )
1855 if( tolower(*pos) ==
'e' )
1858 has_exponent =
true;
1860 has_emptyexponent =
true;
1864 if( (*pos ==
'+') || (*pos ==
'-') )
1868 while( (*pos >=
'0') && (*pos <=
'9') )
1870 has_emptyexponent =
false;
1875 if( has_emptyexponent || !has_digits )
1878 assert(has_exponent || has_dot);
1887 while( ((*pos >=
'0') && (*pos <=
'9') ) || *pos ==
'+' || *pos ==
'-' )
1898 while( (*pos >=
'0') && (*pos <=
'9') )
1907 if( mpq_set_str(value.dpointer->privatevalue, tmp, 10) != 0)
1909 mpq_canonicalize(value.dpointer->privatevalue);
1912 exponent = -decshift;
1913 if( tolower(*pos) ==
'e' )
1916 assert(has_exponent);
1917 for( t = tmp; *pos !=
'\0'; pos++ )
1920 exponent += atol(tmp);
1924 mpz_ui_pow_ui(shiftpower, 10, exponent);
1925 mpq_set_z(shiftpowerRational, shiftpower);
1926 mpq_mul(value.dpointer->privatevalue, value.dpointer->privatevalue, shiftpowerRational);
1928 else if( exponent < 0 )
1930 mpz_ui_pow_ui(shiftpower, 10, -exponent);
1931 mpq_set_z(shiftpowerRational, shiftpower);
1932 mpq_div(value.dpointer->privatevalue, value.dpointer->privatevalue, shiftpowerRational);
1935 mpq_canonicalize(value.dpointer->privatevalue);
1937 mpz_clear(shiftpower);
1938 mpq_clear(shiftpowerRational);
1949 #if defined(_WIN32) || defined(_WIN64) || defined(__APPLE__) 1950 std::stringstream sstream;
1952 return sstream.str();
1954 if( precision <= 0 )
1956 std::stringstream sstream;
1958 return sstream.str();
1966 tmpStream = fmemopen(tmpString, 63,
"w");
1967 mpf_init2(tmpFloat, 256);
1968 mpf_set_q(tmpFloat, r.dpointer->privatevalue);
1969 mpf_out_str(tmpStream, 10, precision, tmpFloat);
1970 mpf_clear(tmpFloat);
1973 std::string retString = std::string(tmpString);
1986 assert(strlen(s) <= MAX_STR_LEN);
1991 if( strchr(s,
'/') != 0 || strpbrk(s,
".eE") == 0 )
1993 pos = (*s ==
'+') ? s + 1 : s;
1994 if( mpq_set_str(value.dpointer->privatevalue, pos, 10) == 0 )
1996 mpq_canonicalize(value.dpointer->privatevalue);
2005 bool has_exponent =
false;
2006 bool has_dot =
false;
2008 bool has_digits =
false;
2009 bool has_emptyexponent =
false;
2010 long int exponent = 0;
2011 long int decshift = 0;
2013 mpz_init(shiftpower);
2014 mpq_t shiftpowerRational;
2015 mpq_init(shiftpowerRational);
2017 char tmp[MAX_STR_LEN];
2022 if( (*pos ==
'+') || (*pos ==
'-') )
2026 while( (*pos >=
'0') && (*pos <=
'9') )
2041 while( (*pos >=
'0') && (*pos <=
'9') )
2049 if( tolower(*pos) ==
'e' )
2052 has_exponent =
true;
2054 has_emptyexponent =
true;
2058 if( (*pos ==
'+') || (*pos ==
'-') )
2062 while( (*pos >=
'0') && (*pos <=
'9') )
2064 has_emptyexponent =
false;
2069 if( has_emptyexponent || !has_digits )
2072 assert(has_exponent || has_dot);
2081 while( ((*pos >=
'0') && (*pos <=
'9') ) || *pos ==
'+' || *pos ==
'-' )
2092 while( (*pos >=
'0') && (*pos <=
'9') )
2101 if( mpq_set_str(value.dpointer->privatevalue, tmp, 10) != 0)
2104 mpq_canonicalize(value.dpointer->privatevalue);
2107 exponent = -decshift;
2108 if( tolower(*pos) ==
'e' )
2111 assert(has_exponent);
2112 for( t = tmp; *pos !=
'\0'; pos++ )
2115 exponent += atol(tmp);
2119 mpz_ui_pow_ui(shiftpower, 10, exponent);
2120 mpq_set_z(shiftpowerRational, shiftpower);
2121 mpq_mul(value.dpointer->privatevalue, value.dpointer->privatevalue, shiftpowerRational);
2123 else if( exponent < 0 )
2125 mpz_ui_pow_ui(shiftpower, 10, -exponent);
2126 mpq_set_z(shiftpowerRational, shiftpower);
2127 mpq_div(value.dpointer->privatevalue, value.dpointer->privatevalue, shiftpowerRational);
2130 mpq_canonicalize(value.dpointer->privatevalue);
2131 mpz_clear(shiftpower);
2132 mpq_clear(shiftpowerRational);
2143 buffer = (
char*) malloc (mpz_sizeinbase(mpq_numref(r.dpointer->privatevalue), 10) + mpz_sizeinbase(mpq_denref(r.dpointer->privatevalue), 10) + 3);
2144 os << mpq_get_str(buffer, 10, r.dpointer->privatevalue);
2154 return mpq_cmp(r.dpointer->privatevalue, s.dpointer->privatevalue);
2162 return (mpq_equal(r.dpointer->privatevalue, s.dpointer->privatevalue) != 0);
2170 return (mpq_equal(r.dpointer->privatevalue, s.dpointer->privatevalue) == 0);
2178 return (mpq_cmp(r.dpointer->privatevalue, s.dpointer->privatevalue) < 0);
2186 return (mpq_cmp(r.dpointer->privatevalue, s.dpointer->privatevalue) <= 0);
2194 return (mpq_cmp(r.dpointer->privatevalue, s.dpointer->privatevalue) > 0);
2202 return (mpq_cmp(r.dpointer->privatevalue, s.dpointer->privatevalue) >= 0);
2211 #ifdef SOPLEX_PERFALT_1 2212 return (mpq_sgn(r.dpointer->privatevalue) == 0);
2214 return (mpq_equal(r.dpointer->privatevalue, Rational::ZERO.dpointer->privatevalue) != 0);
2217 return (mpq_equal(r.dpointer->privatevalue, Rational::POSONE.dpointer->privatevalue) != 0);
2218 else if( s == -1.0 )
2219 return (mpq_equal(r.dpointer->privatevalue, Rational::NEGONE.dpointer->privatevalue) != 0);
2230 #ifdef SOPLEX_PERFALT_1 2231 return (mpq_sgn(r.dpointer->privatevalue) != 0);
2233 return (mpq_equal(r.dpointer->privatevalue, Rational::ZERO.dpointer->privatevalue) == 0);
2236 return (mpq_equal(r.dpointer->privatevalue, Rational::POSONE.dpointer->privatevalue) == 0);
2237 else if( s == -1.0 )
2238 return (mpq_equal(r.dpointer->privatevalue, Rational::NEGONE.dpointer->privatevalue) == 0);
2249 #ifdef SOPLEX_PERFALT_1 2250 return (mpq_sgn(r.dpointer->privatevalue) == -1);
2252 return (mpq_cmp(r.dpointer->privatevalue, Rational::ZERO.dpointer->privatevalue) < 0);
2255 return (mpq_cmp(r.dpointer->privatevalue, Rational::POSONE.dpointer->privatevalue) < 0);
2256 else if( s == -1.0 )
2257 return (mpq_cmp(r.dpointer->privatevalue, Rational::NEGONE.dpointer->privatevalue) < 0);
2268 #ifdef SOPLEX_PERFALT_1 2269 return (mpq_sgn(r.dpointer->privatevalue) <= 0);
2271 return (mpq_cmp(r.dpointer->privatevalue, Rational::ZERO.dpointer->privatevalue) <= 0);
2274 return (mpq_cmp(r.dpointer->privatevalue, Rational::POSONE.dpointer->privatevalue) <= 0);
2275 else if( s == -1.0 )
2276 return (mpq_cmp(r.dpointer->privatevalue, Rational::NEGONE.dpointer->privatevalue) <= 0);
2287 #ifdef SOPLEX_PERFALT_1 2288 return (mpq_sgn(r.dpointer->privatevalue) == 1);
2290 return (mpq_cmp(r.dpointer->privatevalue, Rational::ZERO.dpointer->privatevalue) > 0);
2293 return (mpq_cmp(r.dpointer->privatevalue, Rational::POSONE.dpointer->privatevalue) > 0);
2294 else if( s == -1.0 )
2295 return (mpq_cmp(r.dpointer->privatevalue, Rational::NEGONE.dpointer->privatevalue) > 0);
2306 #ifdef SOPLEX_PERFALT_1 2307 return (mpq_sgn(r.dpointer->privatevalue) >= 0);
2309 return (mpq_cmp(r.dpointer->privatevalue, Rational::ZERO.dpointer->privatevalue) >= 0);
2312 return (mpq_cmp(r.dpointer->privatevalue, Rational::POSONE.dpointer->privatevalue) >= 0);
2313 else if( s == -1.0 )
2314 return (mpq_cmp(r.dpointer->privatevalue, Rational::NEGONE.dpointer->privatevalue) >= 0);
2373 #ifdef SOPLEX_PERFALT_1 2374 return (mpq_sgn(r.dpointer->privatevalue) == 0);
2376 return (mpq_equal(r.dpointer->privatevalue, Rational::ZERO.dpointer->privatevalue) != 0);
2379 return (mpq_equal(r.dpointer->privatevalue, Rational::POSONE.dpointer->privatevalue) != 0);
2380 else if( s == -1.0 )
2381 return (mpq_equal(r.dpointer->privatevalue, Rational::NEGONE.dpointer->privatevalue) != 0);
2392 #ifdef SOPLEX_PERFALT_1 2393 return (mpq_sgn(r.dpointer->privatevalue) != 0);
2395 return (mpq_equal(r.dpointer->privatevalue, Rational::ZERO.dpointer->privatevalue) == 0);
2398 return (mpq_equal(r.dpointer->privatevalue, Rational::POSONE.dpointer->privatevalue) == 0);
2399 else if( s == -1.0 )
2400 return (mpq_equal(r.dpointer->privatevalue, Rational::NEGONE.dpointer->privatevalue) == 0);
2411 #ifdef SOPLEX_PERFALT_1 2412 return (mpq_sgn(r.dpointer->privatevalue) == -1);
2414 return (mpq_cmp(r.dpointer->privatevalue, Rational::ZERO.dpointer->privatevalue) < 0);
2417 return (mpq_cmp(r.dpointer->privatevalue, Rational::POSONE.dpointer->privatevalue) < 0);
2418 else if( s == -1.0 )
2419 return (mpq_cmp(r.dpointer->privatevalue, Rational::NEGONE.dpointer->privatevalue) < 0);
2430 #ifdef SOPLEX_PERFALT_1 2431 return (mpq_sgn(r.dpointer->privatevalue) <= 0);
2433 return (mpq_cmp(r.dpointer->privatevalue, Rational::ZERO.dpointer->privatevalue) <= 0);
2436 return (mpq_cmp(r.dpointer->privatevalue, Rational::POSONE.dpointer->privatevalue) <= 0);
2437 else if( s == -1.0 )
2438 return (mpq_cmp(r.dpointer->privatevalue, Rational::NEGONE.dpointer->privatevalue) <= 0);
2449 #ifdef SOPLEX_PERFALT_1 2450 return (mpq_sgn(r.dpointer->privatevalue) == 1);
2452 return (mpq_cmp(r.dpointer->privatevalue, Rational::ZERO.dpointer->privatevalue) > 0);
2455 return (mpq_cmp(r.dpointer->privatevalue, Rational::POSONE.dpointer->privatevalue) > 0);
2456 else if( s == -1.0 )
2457 return (mpq_cmp(r.dpointer->privatevalue, Rational::NEGONE.dpointer->privatevalue) > 0);
2468 #ifdef SOPLEX_PERFALT_1 2469 return (mpq_sgn(r.dpointer->privatevalue) >= 0);
2471 return (mpq_cmp(r.dpointer->privatevalue, Rational::ZERO.dpointer->privatevalue) >= 0);
2474 return (mpq_cmp(r.dpointer->privatevalue, Rational::POSONE.dpointer->privatevalue) >= 0);
2475 else if( s == -1.0 )
2476 return (mpq_cmp(r.dpointer->privatevalue, Rational::NEGONE.dpointer->privatevalue) >= 0);
2543 mpq_neg(res.dpointer->privatevalue, res.dpointer->privatevalue);
2554 return Rational::ZERO;
2557 else if( d == -1.0 )
2562 mpq_mul(retval.dpointer->privatevalue, retval.dpointer->privatevalue, r.dpointer->privatevalue);
2573 return Rational::ZERO;
2580 else if( d == -1.0 )
2584 mpq_neg(retval.dpointer->privatevalue, retval.dpointer->privatevalue);
2590 mpq_div(retval.dpointer->privatevalue, retval.dpointer->privatevalue, r.dpointer->privatevalue);
2601 #ifdef SOPLEX_PERFALT_1 2602 return (mpq_sgn(r.dpointer->privatevalue) == 0);
2604 return (mpq_equal(r.dpointer->privatevalue, Rational::ZERO.dpointer->privatevalue) != 0);
2607 return (mpq_equal(r.dpointer->privatevalue, Rational::POSONE.dpointer->privatevalue) != 0);
2609 return (mpq_equal(r.dpointer->privatevalue, Rational::NEGONE.dpointer->privatevalue) != 0);
2620 #ifdef SOPLEX_PERFALT_1 2621 return (mpq_sgn(r.dpointer->privatevalue) != 0);
2623 return (mpq_equal(r.dpointer->privatevalue, Rational::ZERO.dpointer->privatevalue) == 0);
2626 return (mpq_equal(r.dpointer->privatevalue, Rational::POSONE.dpointer->privatevalue) == 0);
2628 return (mpq_equal(r.dpointer->privatevalue, Rational::NEGONE.dpointer->privatevalue) == 0);
2639 #ifdef SOPLEX_PERFALT_1 2640 return (mpq_sgn(r.dpointer->privatevalue) == -1);
2642 return (mpq_cmp(r.dpointer->privatevalue, Rational::ZERO.dpointer->privatevalue) < 0);
2645 return (mpq_cmp(r.dpointer->privatevalue, Rational::POSONE.dpointer->privatevalue) < 0);
2647 return (mpq_cmp(r.dpointer->privatevalue, Rational::NEGONE.dpointer->privatevalue) < 0);
2658 #ifdef SOPLEX_PERFALT_1 2659 return (mpq_sgn(r.dpointer->privatevalue) <= 0);
2661 return (mpq_cmp(r.dpointer->privatevalue, Rational::ZERO.dpointer->privatevalue) <= 0);
2664 return (mpq_cmp(r.dpointer->privatevalue, Rational::POSONE.dpointer->privatevalue) <= 0);
2666 return (mpq_cmp(r.dpointer->privatevalue, Rational::NEGONE.dpointer->privatevalue) <= 0);
2677 #ifdef SOPLEX_PERFALT_1 2678 return (mpq_sgn(r.dpointer->privatevalue) == 1);
2680 return (mpq_cmp(r.dpointer->privatevalue, Rational::ZERO.dpointer->privatevalue) > 0);
2683 return (mpq_cmp(r.dpointer->privatevalue, Rational::POSONE.dpointer->privatevalue) > 0);
2685 return (mpq_cmp(r.dpointer->privatevalue, Rational::NEGONE.dpointer->privatevalue) > 0);
2696 #ifdef SOPLEX_PERFALT_1 2697 return (mpq_sgn(r.dpointer->privatevalue) >= 0);
2699 return (mpq_cmp(r.dpointer->privatevalue, Rational::ZERO.dpointer->privatevalue) >= 0);
2702 return (mpq_cmp(r.dpointer->privatevalue, Rational::POSONE.dpointer->privatevalue) >= 0);
2704 return (mpq_cmp(r.dpointer->privatevalue, Rational::NEGONE.dpointer->privatevalue) >= 0);
2771 mpq_neg(res.dpointer->privatevalue, res.dpointer->privatevalue);
2782 return Rational::ZERO;
2790 mpq_mul(retval.dpointer->privatevalue, retval.dpointer->privatevalue, r.dpointer->privatevalue);
2801 return Rational::ZERO;
2812 mpq_neg(retval.dpointer->privatevalue, retval.dpointer->privatevalue);
2818 mpq_div(retval.dpointer->privatevalue, retval.dpointer->privatevalue, r.dpointer->privatevalue);
2829 mpq_abs(res.dpointer->privatevalue, r.dpointer->privatevalue);
2838 return mpq_sgn(r.dpointer->privatevalue);
2847 mpq_neg(res.dpointer->privatevalue, r.dpointer->privatevalue);
2856 assert(vector != 0);
2857 assert(length >= 0);
2862 for(
int i = 0; i < length; i++ )
2873 assert(vector != 0);
2874 assert(length >= 0);
2879 mpz_init_set_ui(lcm, 1);
2881 for(
int i = 0; i < length; i++ )
2882 mpz_lcm(lcm, lcm, mpq_denref(vector[i].getMpqRef()));
2884 int size = (int)mpz_sizeinbase(lcm, base);
2896 assert(vector != 0);
2897 assert(length >= 0);
2902 for(
int i = 0; i < length; i++ )
2904 size_t dsize = mpz_sizeinbase(mpq_denref(vector[i].getMpqRef()), base);
2967 this->privatevalue = r;
2974 this->privatevalue = (
long double)(r);
2981 this->privatevalue = (
long double)(i);
3111 Rational::operator double()
const 3119 Rational::operator
long double()
const 3437 return sizeof(
long double);
3454 std::stringstream sstream;
3455 sstream << std::setprecision(precision <= 0 ? 16 : precision) << r;
3456 return sstream.str();
3942 assert(vector != 0);
3943 assert(length >= 0);
3948 for(
int i = 0; i < length; i++ )
3959 assert(vector != 0);
3960 assert(length >= 0);
3971 assert(vector != 0);
3972 assert(length >= 0);
3980 #endif // SOPLEX_WITH_GMP Rational & addProduct(const Rational &r, const Rational &s)
add product of two rationals
bool isAdjacentTo(const double &d) const
checks if d is exactly equal to the Rational and if not, if it is one of the two adjacent doubles ...
bool isNextTo(const double &d)
checks if d is the closest number that can be represented by double
THREADLOCAL const Real infinity
friend Rational spxAbs(const Rational &r)
Absolute.
Memory allocation routines.
friend std::string rationalToString(const Rational &r, const int precision)
convert rational number to string
int dlcmSizeRational(const Rational *vector, const int length, const int base)
Size of least common multiple of denominators in rational vector.
long double privatevalue
value
friend bool operator<(const Rational &r, const Rational &s)
less than operator
Private & operator=(const int &i)
assignment operator from int
Rational operator*(const Rational &r) const
multiplication operator
int sizeInBase(const int base=2) const
Size in specified base (bit size for base 2)
friend bool operator<=(const Rational &r, const Rational &s)
less than or equal to operator
Rational operator-(const Rational &r) const
subtraction operator
friend bool operator!=(const Rational &r, const Rational &s)
inequality operator
Rational & subProduct(const Rational &r, const Rational &s)
subtract product of two rationals
Rational & invert()
inversion
friend bool operator>=(const Rational &r, const Rational &s)
greater than or equal to operator
int totalSizeRational(const Rational *vector, const int length, const int base)
Total size of rational vector.
Wrapper for GMP type mpq_class.We wrap mpq_class so that we can replace it by a double type if GMP is...
static void disableListMem()
disables list memory
Private & operator=(const long double &r)
assignment operator from long double
Private & operator=(const double &r)
assignment operator from double
Rational & operator/=(const Rational &r)
division assignment operator
Rational & operator-=(const Rational &r)
subtraction assignment operator
void spx_alloc(T &p, int n=1)
Allocate memory.
static void freeListMem()
frees the unused rational elements in the memory list
int dmaxSizeRational(const Rational *vector, const int length, const int base)
Size of largest denominator in rational vector.
Private()
default constructor
Rational & operator*=(const Rational &r)
multiplication assignment operator operator
Private & operator=(const Private &p)
assignment operator
Private(const double &r)
constructor from double
bool readString(const char *s)
read Rational from string
static int precision()
returns precision of Rational implementation, i.e., number of bits used to store Rational numbers (IN...
#define DEFAULT_EPS_ZERO
default allowed additive zero: 1.0 + EPS_ZERO == 1.0
friend int sign(const Rational &r)
Sign function; returns 1 if r > 0, 0 if r = 0, and -1 if r < 0.
Defines the "Pimpl"-class Private.
friend std::ostream & operator<<(std::ostream &os, const Rational &q)
print Rational
Private(const int &i)
constructor from int
static void enableListMem()
enables list memory
Private(const long double &r)
constructor from long double
Debugging, floating point type and parameter definitions.
friend bool operator==(const Rational &r, const Rational &s)
equality operator
friend int compareRational(const Rational &r, const Rational &s)
comparison operator returning a positive value if r > s, zero if r = s, and a negative value if r < s...
Rational operator+(const Rational &r) const
addition operator
Everything should be within this namespace.
Rational operator/(const Rational &r) const
division operator
Real spxNextafter(Real x, Real y)
friend bool readStringRational(const char *s, Rational &value)
read Rational from string
Rational & operator=(const Rational &)
assignment operator
Rational & subQuotient(const Rational &r, const Rational &s)
subtract quotient of two rationals, r divided by s
friend bool operator>(const Rational &r, const Rational &s)
greater than operator
Private(const Private &p)
copy constructor
Rational()
default constructor
#define THREADLOCAL
SOPLEX_DEBUG.
void spx_free(T &p)
Release memory.
Rational & addQuotient(const Rational &r, const Rational &s)
add quotient of two rationals, r divided by s
Rational & operator+=(const Rational &r)
addition assignment operator
Rational & powRound()
round up to next power of two