34 #ifdef SOPLEX_WITH_GMP 39 #define SOPLEX_PERFALT_1 42 #define SOPLEX_PERFALT_2a 45 #define SOPLEX_PERFALT_2b 48 #define SOPLEX_PERFALT_3 51 #define SOPLEX_PERFALT_4 54 #define SOPLEX_PERFALT_5a 57 #define SOPLEX_PERFALT_5b 62 #ifdef SOPLEX_WITH_GMP 65 const Rational Rational::ZERO(0,
true);
68 const Rational Rational::POSONE(1,
true);
71 const Rational Rational::NEGONE(-1,
true);
76 #ifdef SOPLEX_NOLISTMEM 87 #ifdef SOPLEX_WITH_GMP 88 THREADLOCAL IdList< Rational::Private > Rational::unusedPrivateList(0, 0,
true);
92 class Rational::Private
105 mpq_init(privatevalue);
115 mpq_init(privatevalue);
116 mpq_set(this->privatevalue, p.privatevalue);
124 mpq_init(privatevalue);
125 if( r == (
long double)(1.0) )
127 else if( r == (
long double)(-1.0) )
129 else if( r == (
long double)(0.0) )
134 mpq_set_d(privatevalue,
double(r));
142 mpq_init(privatevalue);
152 mpq_set_d(privatevalue, r);
160 mpq_init(privatevalue);
170 mpq_set_si(privatevalue, i, 1);
178 mpq_init(privatevalue);
179 mpq_set(privatevalue, q);
185 mpq_clear(privatevalue);
191 #ifdef SOPLEX_PERFALT_4 192 if( mpq_equal(this->privatevalue, p.privatevalue) != 0 )
197 mpq_set(this->privatevalue, p.privatevalue);
205 if( r == (
long double)(0.0) )
207 #ifdef SOPLEX_PERFALT_5a 208 #ifdef SOPLEX_PERFALT_1 209 if( mpq_sgn(privatevalue) != 0 )
216 else if( r == (
long double)(1.0) )
218 #ifdef SOPLEX_PERFALT_5b 223 else if( r == (
long double)(-1.0) )
225 #ifdef SOPLEX_PERFALT_5b 231 mpq_set_d(this->privatevalue,
double(r));
242 #ifdef SOPLEX_PERFALT_5a 243 #ifdef SOPLEX_PERFALT_1 244 if( mpq_sgn(privatevalue) != 0 )
253 #ifdef SOPLEX_PERFALT_5b 260 #ifdef SOPLEX_PERFALT_5b 266 mpq_set_d(privatevalue, r);
277 #ifdef SOPLEX_PERFALT_5a 278 #ifdef SOPLEX_PERFALT_1 279 if( mpq_sgn(privatevalue) != 0 )
288 #ifdef SOPLEX_PERFALT_5b 295 #ifdef SOPLEX_PERFALT_5b 301 mpq_set_si(privatevalue, i, 1);
309 #ifdef SOPLEX_PERFALT_4 310 if( mpq_equal(this->privatevalue, q) != 0 )
315 mpq_set(this->privatevalue, q);
363 if( Rational::useListMem )
365 dpointer = unusedPrivateList.last();
369 assert(unusedPrivateList.first() != 0);
374 assert(unusedPrivateList.first() == 0);
381 assert(unusedPrivateList.length() == 0);
395 if( Rational::useListMem )
397 dpointer = unusedPrivateList.last();
401 assert(unusedPrivateList.first() != 0);
407 assert(unusedPrivateList.first() == 0);
414 assert(unusedPrivateList.length() == 0);
428 if( Rational::useListMem )
430 dpointer = unusedPrivateList.last();
434 assert(unusedPrivateList.first() != 0);
440 assert(unusedPrivateList.first() == 0);
447 assert(unusedPrivateList.length() == 0);
461 if( Rational::useListMem )
463 dpointer = unusedPrivateList.last();
467 assert(unusedPrivateList.first() != 0);
473 assert(unusedPrivateList.first() == 0);
480 assert(unusedPrivateList.length() == 0);
494 if( Rational::useListMem )
496 dpointer = unusedPrivateList.last();
500 assert(unusedPrivateList.first() != 0);
506 assert(unusedPrivateList.first() == 0);
513 assert(unusedPrivateList.length() == 0);
527 if( Rational::useListMem )
529 dpointer = unusedPrivateList.last();
533 assert(unusedPrivateList.first() != 0);
539 assert(unusedPrivateList.first() == 0);
546 assert(unusedPrivateList.length() == 0);
560 assert(Rational::useListMem || unusedPrivateList.length() == 0);
562 if( !Rational::useListMem ||
this == &Rational::ZERO ||
this == &Rational::POSONE ||
this == &Rational::NEGONE )
582 assert(Rational::useListMem || unusedPrivateList.length() == 0);
583 Rational::useListMem =
true;
596 unusedPrivateList.clear(
true);
597 assert(unusedPrivateList.length() == 0);
606 Rational::useListMem =
false;
657 Rational::operator double()
const 659 #ifdef SOPLEX_PERFALT_3 660 #ifdef SOPLEX_PERFALT_1 666 else if( mpq_equal(this->
dpointer->
privatevalue, Rational::POSONE.dpointer->privatevalue) != 0 )
668 else if( mpq_equal(this->
dpointer->
privatevalue, Rational::NEGONE.dpointer->privatevalue) != 0 )
678 Rational::operator
long double()
const 680 #ifdef SOPLEX_PERFALT_3 681 #ifdef SOPLEX_PERFALT_1 687 else if( mpq_equal(this->
dpointer->
privatevalue, Rational::POSONE.dpointer->privatevalue) != 0 )
689 else if( mpq_equal(this->
dpointer->
privatevalue, Rational::NEGONE.dpointer->privatevalue) != 0 )
699 const mpq_t* Rational::getMpqPtr()
const 707 const mpq_t& Rational::getMpqRef()
const 715 mpq_t* Rational::getMpqPtr_w()
const 723 mpq_t& Rational::getMpqRef_w()
const 733 #ifdef SOPLEX_PERFALT_2a 734 #ifdef SOPLEX_PERFALT_1 735 if( mpq_sgn(r.dpointer->privatevalue) == 0 )
740 if( mpq_equal(r.dpointer->privatevalue, Rational::ZERO.dpointer->privatevalue) != 0 )
748 mpq_add(retval.dpointer->privatevalue, this->dpointer->privatevalue, r.dpointer->privatevalue);
757 #ifdef SOPLEX_PERFALT_2a 758 #ifdef SOPLEX_PERFALT_1 759 if( mpq_sgn(r.dpointer->privatevalue) == 0 )
764 if( mpq_equal(r.dpointer->privatevalue, Rational::ZERO.dpointer->privatevalue) != 0 )
784 #ifdef SOPLEX_PERFALT_2a 785 #ifdef SOPLEX_PERFALT_1 795 mpq_add(retval.dpointer->privatevalue, this->dpointer->privatevalue, retval.dpointer->privatevalue);
806 return (*
this += Rational::POSONE);
808 return (*
this += Rational::NEGONE);
811 #ifdef SOPLEX_PERFALT_2a 812 #ifdef SOPLEX_PERFALT_1 822 mpq_add(this->
dpointer->
privatevalue, this->dpointer->privatevalue, retval.dpointer->privatevalue);
837 #ifdef SOPLEX_PERFALT_2a 838 #ifdef SOPLEX_PERFALT_1 848 mpq_add(retval.dpointer->privatevalue, this->dpointer->privatevalue, retval.dpointer->privatevalue);
859 return (*
this += Rational::POSONE);
861 return (*
this += Rational::NEGONE);
864 #ifdef SOPLEX_PERFALT_2a 865 #ifdef SOPLEX_PERFALT_1 875 mpq_add(this->
dpointer->
privatevalue, this->dpointer->privatevalue, retval.dpointer->privatevalue);
886 #ifdef SOPLEX_PERFALT_2a 887 #ifdef SOPLEX_PERFALT_1 888 if( mpq_sgn(r.dpointer->privatevalue) == 0 )
893 if( mpq_equal(r.dpointer->privatevalue, Rational::ZERO.dpointer->privatevalue) != 0 )
901 mpq_sub(retval.dpointer->privatevalue, this->dpointer->privatevalue, r.dpointer->privatevalue);
910 #ifdef SOPLEX_PERFALT_2a 911 #ifdef SOPLEX_PERFALT_1 912 if( mpq_sgn(r.dpointer->privatevalue) == 0 )
921 if( mpq_equal(r.dpointer->privatevalue, Rational::ZERO.dpointer->privatevalue) != 0 )
945 #ifdef SOPLEX_PERFALT_2a 946 #ifdef SOPLEX_PERFALT_1 956 mpq_sub(retval.dpointer->privatevalue, this->dpointer->privatevalue, retval.dpointer->privatevalue);
968 return (*
this -= Rational::POSONE);
970 return (*
this -= Rational::NEGONE);
973 #ifdef SOPLEX_PERFALT_2a 974 #ifdef SOPLEX_PERFALT_1 984 mpq_sub(this->
dpointer->
privatevalue, this->dpointer->privatevalue, retval.dpointer->privatevalue);
999 #ifdef SOPLEX_PERFALT_2a 1000 #ifdef SOPLEX_PERFALT_1 1010 mpq_sub(retval.dpointer->privatevalue, this->dpointer->privatevalue, retval.dpointer->privatevalue);
1022 return (*
this -= Rational::POSONE);
1024 return (*
this -= Rational::NEGONE);
1027 #ifdef SOPLEX_PERFALT_2a 1028 #ifdef SOPLEX_PERFALT_1 1030 return (*
this = -d);
1033 return (*
this = -d);
1038 mpq_sub(this->
dpointer->
privatevalue, this->dpointer->privatevalue, retval.dpointer->privatevalue);
1049 #ifdef SOPLEX_PERFALT_2b 1050 #ifdef SOPLEX_PERFALT_1 1051 if( mpq_sgn(r.dpointer->privatevalue) == 0 )
1052 return Rational::ZERO;
1054 return Rational::ZERO;
1056 if( mpq_equal(r.dpointer->privatevalue, Rational::ZERO.dpointer->privatevalue) != 0 )
1057 return Rational::ZERO;
1059 return Rational::ZERO;
1061 else if( mpq_equal(r.dpointer->privatevalue, Rational::POSONE.dpointer->privatevalue) != 0 )
1063 else if( mpq_equal(this->
dpointer->
privatevalue, Rational::POSONE.dpointer->privatevalue) != 0 )
1065 else if( mpq_equal(r.dpointer->privatevalue, Rational::NEGONE.dpointer->privatevalue) != 0 )
1067 else if( mpq_equal(this->
dpointer->
privatevalue, Rational::NEGONE.dpointer->privatevalue) != 0 )
1072 mpq_mul(retval.dpointer->privatevalue, this->dpointer->privatevalue, r.dpointer->privatevalue);
1081 #ifdef SOPLEX_PERFALT_2b 1082 #ifdef SOPLEX_PERFALT_1 1083 if( mpq_sgn(r.dpointer->privatevalue) == 0 )
1084 return (*
this = Rational::ZERO);
1088 if( mpq_equal(r.dpointer->privatevalue, Rational::ZERO.dpointer->privatevalue) != 0 )
1089 return (*
this = Rational::ZERO);
1093 else if( mpq_equal(r.dpointer->privatevalue, Rational::POSONE.dpointer->privatevalue) != 0 )
1095 else if( mpq_equal(this->
dpointer->
privatevalue, Rational::POSONE.dpointer->privatevalue) != 0 )
1097 else if( mpq_equal(r.dpointer->privatevalue, Rational::NEGONE.dpointer->privatevalue) != 0 )
1102 else if( mpq_equal(this->
dpointer->
privatevalue, Rational::NEGONE.dpointer->privatevalue) != 0 )
1119 return Rational::ZERO;
1122 else if( d == -1.0 )
1125 mpq_neg(retval.dpointer->privatevalue, this->dpointer->privatevalue);
1130 #ifdef SOPLEX_PERFALT_2b 1131 #ifdef SOPLEX_PERFALT_1 1133 return Rational::ZERO;
1136 return Rational::ZERO;
1138 else if( mpq_equal(this->
dpointer->
privatevalue, Rational::POSONE.dpointer->privatevalue) != 0 )
1140 else if( mpq_equal(this->
dpointer->
privatevalue, Rational::NEGONE.dpointer->privatevalue) != 0 )
1145 mpq_mul(retval.dpointer->privatevalue, retval.dpointer->privatevalue, this->dpointer->privatevalue);
1156 return (*
this = Rational::ZERO);
1159 else if( d == -1.0 )
1166 #ifdef SOPLEX_PERFALT_2b 1167 #ifdef SOPLEX_PERFALT_1 1174 else if( mpq_equal(this->
dpointer->
privatevalue, Rational::POSONE.dpointer->privatevalue) != 0 )
1176 else if( mpq_equal(this->
dpointer->
privatevalue, Rational::NEGONE.dpointer->privatevalue) != 0 )
1185 mpq_mul(this->
dpointer->
privatevalue, this->dpointer->privatevalue, retval.dpointer->privatevalue);
1196 return Rational::ZERO;
1202 mpq_neg(retval.dpointer->privatevalue, this->dpointer->privatevalue);
1207 #ifdef SOPLEX_PERFALT_2b 1208 #ifdef SOPLEX_PERFALT_1 1210 return Rational::ZERO;
1213 return Rational::ZERO;
1215 else if( mpq_equal(this->
dpointer->
privatevalue, Rational::POSONE.dpointer->privatevalue) != 0 )
1217 else if( mpq_equal(this->
dpointer->
privatevalue, Rational::NEGONE.dpointer->privatevalue) != 0 )
1222 mpq_mul(retval.dpointer->privatevalue, retval.dpointer->privatevalue, this->dpointer->privatevalue);
1233 return (*
this = Rational::ZERO);
1243 #ifdef SOPLEX_PERFALT_2b 1244 #ifdef SOPLEX_PERFALT_1 1251 else if( mpq_equal(this->
dpointer->
privatevalue, Rational::POSONE.dpointer->privatevalue) != 0 )
1253 else if( mpq_equal(this->
dpointer->
privatevalue, Rational::NEGONE.dpointer->privatevalue) != 0 )
1262 mpq_mul(this->
dpointer->
privatevalue, this->dpointer->privatevalue, retval.dpointer->privatevalue);
1272 #ifdef SOPLEX_PERFALT_2b 1273 #ifdef SOPLEX_PERFALT_1 1275 return Rational::ZERO;
1278 return Rational::ZERO;
1280 else if( mpq_equal(r.dpointer->privatevalue, Rational::POSONE.dpointer->privatevalue) != 0 )
1282 else if( mpq_equal(this->
dpointer->
privatevalue, Rational::POSONE.dpointer->privatevalue) != 0 )
1288 else if( mpq_equal(r.dpointer->privatevalue, Rational::NEGONE.dpointer->privatevalue) != 0 )
1290 else if( mpq_equal(this->
dpointer->
privatevalue, Rational::NEGONE.dpointer->privatevalue) != 0 )
1294 mpq_neg(retval.dpointer->privatevalue, retval.dpointer->privatevalue);
1300 mpq_div(retval.dpointer->privatevalue, this->dpointer->privatevalue, r.dpointer->privatevalue);
1309 #ifdef SOPLEX_PERFALT_2b 1310 #ifdef SOPLEX_PERFALT_1 1317 else if( mpq_equal(r.dpointer->privatevalue, Rational::POSONE.dpointer->privatevalue) != 0 )
1319 else if( mpq_equal(r.dpointer->privatevalue, Rational::NEGONE.dpointer->privatevalue) != 0 )
1324 else if( mpq_equal(this->
dpointer->
privatevalue, Rational::POSONE.dpointer->privatevalue) != 0 )
1329 else if( mpq_equal(this->
dpointer->
privatevalue, Rational::NEGONE.dpointer->privatevalue) != 0 )
1348 else if( d == -1.0 )
1352 #ifdef SOPLEX_PERFALT_2b 1353 #ifdef SOPLEX_PERFALT_1 1355 return Rational::ZERO;
1358 return Rational::ZERO;
1360 else if( mpq_equal(this->
dpointer->
privatevalue, Rational::POSONE.dpointer->privatevalue) != 0 )
1366 else if( mpq_equal(this->
dpointer->
privatevalue, Rational::NEGONE.dpointer->privatevalue) != 0 )
1370 mpq_neg(retval.dpointer->privatevalue, retval.dpointer->privatevalue);
1376 mpq_div(retval.dpointer->privatevalue, this->dpointer->privatevalue, retval.dpointer->privatevalue);
1388 else if( d == -1.0 )
1395 #ifdef SOPLEX_PERFALT_2b 1396 #ifdef SOPLEX_PERFALT_1 1403 else if( mpq_equal(this->
dpointer->
privatevalue, Rational::POSONE.dpointer->privatevalue) != 0 )
1409 else if( mpq_equal(this->
dpointer->
privatevalue, Rational::NEGONE.dpointer->privatevalue) != 0 )
1418 mpq_div(this->
dpointer->
privatevalue, this->dpointer->privatevalue, retval.dpointer->privatevalue);
1434 #ifdef SOPLEX_PERFALT_2b 1435 #ifdef SOPLEX_PERFALT_1 1437 return Rational::ZERO;
1440 return Rational::ZERO;
1442 else if( mpq_equal(this->
dpointer->
privatevalue, Rational::POSONE.dpointer->privatevalue) != 0 )
1448 else if( mpq_equal(this->
dpointer->
privatevalue, Rational::NEGONE.dpointer->privatevalue) != 0 )
1452 mpq_neg(retval.dpointer->privatevalue, retval.dpointer->privatevalue);
1458 mpq_div(retval.dpointer->privatevalue, this->dpointer->privatevalue, retval.dpointer->privatevalue);
1477 #ifdef SOPLEX_PERFALT_2b 1478 #ifdef SOPLEX_PERFALT_1 1485 else if( mpq_equal(this->
dpointer->
privatevalue, Rational::POSONE.dpointer->privatevalue) != 0 )
1491 else if( mpq_equal(this->
dpointer->
privatevalue, Rational::NEGONE.dpointer->privatevalue) != 0 )
1500 mpq_div(this->
dpointer->
privatevalue, this->dpointer->privatevalue, retval.dpointer->privatevalue);
1510 #ifdef SOPLEX_PERFALT_2b 1511 if( mpq_equal(r.dpointer->privatevalue, Rational::POSONE.dpointer->privatevalue) != 0 )
1516 else if( mpq_equal(s.dpointer->privatevalue, Rational::POSONE.dpointer->privatevalue) != 0 )
1521 else if( mpq_equal(r.dpointer->privatevalue, Rational::NEGONE.dpointer->privatevalue) != 0 )
1526 else if( mpq_equal(s.dpointer->privatevalue, Rational::NEGONE.dpointer->privatevalue) != 0 )
1531 #if 0 // currently, SoPlex calls this method only with nonzero r and s, hence we do not check this case 1532 #ifdef SOPLEX_PERFALT_1 1533 else if( mpq_sgn(r.dpointer->privatevalue) == 0 )
1535 else if( mpq_sgn(s.dpointer->privatevalue) == 0 )
1538 else if( mpq_equal(r.dpointer->privatevalue, Rational::ZERO.dpointer->privatevalue) != 0 )
1540 else if( mpq_equal(s.dpointer->privatevalue, Rational::ZERO.dpointer->privatevalue) != 0 )
1547 mpq_mul(product.dpointer->privatevalue, product.dpointer->privatevalue, s.dpointer->privatevalue);
1548 mpq_add(this->
dpointer->
privatevalue, this->dpointer->privatevalue, product.dpointer->privatevalue);
1557 #ifdef SOPLEX_PERFALT_2b 1558 if( mpq_equal(r.dpointer->privatevalue, Rational::POSONE.dpointer->privatevalue) != 0 )
1563 else if( mpq_equal(s.dpointer->privatevalue, Rational::POSONE.dpointer->privatevalue) != 0 )
1568 else if( mpq_equal(r.dpointer->privatevalue, Rational::NEGONE.dpointer->privatevalue) != 0 )
1573 else if( mpq_equal(s.dpointer->privatevalue, Rational::NEGONE.dpointer->privatevalue) != 0 )
1578 #if 0 // currently, SoPlex calls this method only with nonzero r and s, hence we do not check this case 1579 #ifdef SOPLEX_PERFALT_1 1580 if( mpq_sgn(r.dpointer->privatevalue) == 0 )
1582 else if( mpq_sgn(s.dpointer->privatevalue) == 0 )
1585 if( mpq_equal(r.dpointer->privatevalue, Rational::ZERO.dpointer->privatevalue) != 0 )
1587 else if( mpq_equal(s.dpointer->privatevalue, Rational::ZERO.dpointer->privatevalue) != 0 )
1594 mpq_mul(product.dpointer->privatevalue, product.dpointer->privatevalue, s.dpointer->privatevalue);
1595 mpq_sub(this->
dpointer->
privatevalue, this->dpointer->privatevalue, product.dpointer->privatevalue);
1604 #ifdef SOPLEX_PERFALT_2b 1605 #ifdef SOPLEX_PERFALT_1 1606 if( mpq_sgn(r.dpointer->privatevalue) == 0 )
1609 if( mpq_equal(r.dpointer->privatevalue, Rational::ZERO.dpointer->privatevalue) != 0 )
1612 else if( mpq_equal(s.dpointer->privatevalue, Rational::POSONE.dpointer->privatevalue) != 0 )
1617 else if( mpq_equal(s.dpointer->privatevalue, Rational::NEGONE.dpointer->privatevalue) != 0 )
1625 mpq_div(quotient.dpointer->privatevalue, quotient.dpointer->privatevalue, s.dpointer->privatevalue);
1626 mpq_add(this->
dpointer->
privatevalue, this->dpointer->privatevalue, quotient.dpointer->privatevalue);
1635 #ifdef SOPLEX_PERFALT_2b 1636 #ifdef SOPLEX_PERFALT_1 1637 if( mpq_sgn(r.dpointer->privatevalue) == 0 )
1640 if( mpq_equal(r.dpointer->privatevalue, Rational::ZERO.dpointer->privatevalue) != 0 )
1643 else if( mpq_equal(s.dpointer->privatevalue, Rational::POSONE.dpointer->privatevalue) != 0 )
1648 else if( mpq_equal(s.dpointer->privatevalue, Rational::NEGONE.dpointer->privatevalue) != 0 )
1656 mpq_div(quotient.dpointer->privatevalue, quotient.dpointer->privatevalue, s.dpointer->privatevalue);
1657 mpq_sub(this->
dpointer->
privatevalue, this->dpointer->privatevalue, quotient.dpointer->privatevalue);
1681 mpz_sub_ui(roundval, roundval, 1);
1683 MSG_DEBUG( std::cout <<
" --> " << mpz_get_str(0, 10, roundval) <<
"\n" );
1685 size_t binlog = mpz_sizeinbase(roundval, 2);
1687 MSG_DEBUG( std::cout <<
" --> 2^" << binlog <<
"\n" );
1689 mpz_ui_pow_ui(roundval, 2, binlog);
1691 MSG_DEBUG( std::cout <<
" --> " << mpz_get_str(0, 10, roundval) <<
"\n" );
1694 mpz_clear(roundval);
1762 return ((a == d) || (b == d));
1784 #define MAX_STR_LEN 10000 1789 assert(strlen(s) <= MAX_STR_LEN);
1795 if( strchr(s,
'/') != 0 || strpbrk(s,
".eE") == 0 )
1797 pos = (*s ==
'+') ? s + 1 : s;
1798 if( mpq_set_str(value.dpointer->privatevalue, pos, 10) == 0 )
1800 mpq_canonicalize(value.dpointer->privatevalue);
1810 bool has_exponent =
false;
1811 bool has_dot =
false;
1813 bool has_digits =
false;
1814 bool has_emptyexponent =
false;
1815 long int exponent = 0;
1816 long int decshift = 0;
1818 mpz_init(shiftpower);
1819 mpq_t shiftpowerRational;
1820 mpq_init(shiftpowerRational);
1822 char tmp[MAX_STR_LEN];
1827 if( (*pos ==
'+') || (*pos ==
'-') )
1831 while( (*pos >=
'0') && (*pos <=
'9') )
1846 while( (*pos >=
'0') && (*pos <=
'9') )
1854 if( tolower(*pos) ==
'e' )
1857 has_exponent =
true;
1859 has_emptyexponent =
true;
1863 if( (*pos ==
'+') || (*pos ==
'-') )
1867 while( (*pos >=
'0') && (*pos <=
'9') )
1869 has_emptyexponent =
false;
1874 if( has_emptyexponent || !has_digits )
1877 assert(has_exponent || has_dot);
1886 while( ((*pos >=
'0') && (*pos <=
'9') ) || *pos ==
'+' || *pos ==
'-' )
1897 while( (*pos >=
'0') && (*pos <=
'9') )
1906 if( mpq_set_str(value.dpointer->privatevalue, tmp, 10) != 0)
1908 mpq_canonicalize(value.dpointer->privatevalue);
1911 exponent = -decshift;
1912 if( tolower(*pos) ==
'e' )
1915 assert(has_exponent);
1916 for( t = tmp; *pos !=
'\0'; pos++ )
1919 exponent += atol(tmp);
1923 mpz_ui_pow_ui(shiftpower, 10, exponent);
1924 mpq_set_z(shiftpowerRational, shiftpower);
1925 mpq_mul(value.dpointer->privatevalue, value.dpointer->privatevalue, shiftpowerRational);
1927 else if( exponent < 0 )
1929 mpz_ui_pow_ui(shiftpower, 10, -exponent);
1930 mpq_set_z(shiftpowerRational, shiftpower);
1931 mpq_div(value.dpointer->privatevalue, value.dpointer->privatevalue, shiftpowerRational);
1934 mpq_canonicalize(value.dpointer->privatevalue);
1936 mpz_clear(shiftpower);
1937 mpq_clear(shiftpowerRational);
1948 #if defined(_WIN32) || defined(_WIN64) || defined(__APPLE__) 1949 std::stringstream sstream;
1951 return sstream.str();
1953 if( precision <= 0 )
1955 std::stringstream sstream;
1957 return sstream.str();
1965 tmpStream = fmemopen(tmpString, 63,
"w");
1966 mpf_init2(tmpFloat, 256);
1967 mpf_set_q(tmpFloat, r.dpointer->privatevalue);
1968 mpf_out_str(tmpStream, 10, precision, tmpFloat);
1969 mpf_clear(tmpFloat);
1972 std::string retString = std::string(tmpString);
1985 assert(strlen(s) <= MAX_STR_LEN);
1990 if( strchr(s,
'/') != 0 || strpbrk(s,
".eE") == 0 )
1992 pos = (*s ==
'+') ? s + 1 : s;
1993 if( mpq_set_str(value.dpointer->privatevalue, pos, 10) == 0 )
1995 mpq_canonicalize(value.dpointer->privatevalue);
2004 bool has_exponent =
false;
2005 bool has_dot =
false;
2007 bool has_digits =
false;
2008 bool has_emptyexponent =
false;
2009 long int exponent = 0;
2010 long int decshift = 0;
2012 mpz_init(shiftpower);
2013 mpq_t shiftpowerRational;
2014 mpq_init(shiftpowerRational);
2016 char tmp[MAX_STR_LEN];
2021 if( (*pos ==
'+') || (*pos ==
'-') )
2025 while( (*pos >=
'0') && (*pos <=
'9') )
2040 while( (*pos >=
'0') && (*pos <=
'9') )
2048 if( tolower(*pos) ==
'e' )
2051 has_exponent =
true;
2053 has_emptyexponent =
true;
2057 if( (*pos ==
'+') || (*pos ==
'-') )
2061 while( (*pos >=
'0') && (*pos <=
'9') )
2063 has_emptyexponent =
false;
2068 if( has_emptyexponent || !has_digits )
2071 assert(has_exponent || has_dot);
2080 while( ((*pos >=
'0') && (*pos <=
'9') ) || *pos ==
'+' || *pos ==
'-' )
2091 while( (*pos >=
'0') && (*pos <=
'9') )
2100 if( mpq_set_str(value.dpointer->privatevalue, tmp, 10) != 0)
2103 mpq_canonicalize(value.dpointer->privatevalue);
2106 exponent = -decshift;
2107 if( tolower(*pos) ==
'e' )
2110 assert(has_exponent);
2111 for( t = tmp; *pos !=
'\0'; pos++ )
2114 exponent += atol(tmp);
2118 mpz_ui_pow_ui(shiftpower, 10, exponent);
2119 mpq_set_z(shiftpowerRational, shiftpower);
2120 mpq_mul(value.dpointer->privatevalue, value.dpointer->privatevalue, shiftpowerRational);
2122 else if( exponent < 0 )
2124 mpz_ui_pow_ui(shiftpower, 10, -exponent);
2125 mpq_set_z(shiftpowerRational, shiftpower);
2126 mpq_div(value.dpointer->privatevalue, value.dpointer->privatevalue, shiftpowerRational);
2129 mpq_canonicalize(value.dpointer->privatevalue);
2130 mpz_clear(shiftpower);
2131 mpq_clear(shiftpowerRational);
2142 buffer = (
char*) malloc (mpz_sizeinbase(mpq_numref(r.dpointer->privatevalue), 10) + mpz_sizeinbase(mpq_denref(r.dpointer->privatevalue), 10) + 3);
2143 os << mpq_get_str(buffer, 10, r.dpointer->privatevalue);
2153 return mpq_cmp(r.dpointer->privatevalue, s.dpointer->privatevalue);
2161 return (mpq_equal(r.dpointer->privatevalue, s.dpointer->privatevalue) != 0);
2169 return (mpq_equal(r.dpointer->privatevalue, s.dpointer->privatevalue) == 0);
2177 return (mpq_cmp(r.dpointer->privatevalue, s.dpointer->privatevalue) < 0);
2185 return (mpq_cmp(r.dpointer->privatevalue, s.dpointer->privatevalue) <= 0);
2193 return (mpq_cmp(r.dpointer->privatevalue, s.dpointer->privatevalue) > 0);
2201 return (mpq_cmp(r.dpointer->privatevalue, s.dpointer->privatevalue) >= 0);
2210 #ifdef SOPLEX_PERFALT_1 2211 return (mpq_sgn(r.dpointer->privatevalue) == 0);
2213 return (mpq_equal(r.dpointer->privatevalue, Rational::ZERO.dpointer->privatevalue) != 0);
2216 return (mpq_equal(r.dpointer->privatevalue, Rational::POSONE.dpointer->privatevalue) != 0);
2217 else if( s == -1.0 )
2218 return (mpq_equal(r.dpointer->privatevalue, Rational::NEGONE.dpointer->privatevalue) != 0);
2229 #ifdef SOPLEX_PERFALT_1 2230 return (mpq_sgn(r.dpointer->privatevalue) != 0);
2232 return (mpq_equal(r.dpointer->privatevalue, Rational::ZERO.dpointer->privatevalue) == 0);
2235 return (mpq_equal(r.dpointer->privatevalue, Rational::POSONE.dpointer->privatevalue) == 0);
2236 else if( s == -1.0 )
2237 return (mpq_equal(r.dpointer->privatevalue, Rational::NEGONE.dpointer->privatevalue) == 0);
2248 #ifdef SOPLEX_PERFALT_1 2249 return (mpq_sgn(r.dpointer->privatevalue) == -1);
2251 return (mpq_cmp(r.dpointer->privatevalue, Rational::ZERO.dpointer->privatevalue) < 0);
2254 return (mpq_cmp(r.dpointer->privatevalue, Rational::POSONE.dpointer->privatevalue) < 0);
2255 else if( s == -1.0 )
2256 return (mpq_cmp(r.dpointer->privatevalue, Rational::NEGONE.dpointer->privatevalue) < 0);
2267 #ifdef SOPLEX_PERFALT_1 2268 return (mpq_sgn(r.dpointer->privatevalue) <= 0);
2270 return (mpq_cmp(r.dpointer->privatevalue, Rational::ZERO.dpointer->privatevalue) <= 0);
2273 return (mpq_cmp(r.dpointer->privatevalue, Rational::POSONE.dpointer->privatevalue) <= 0);
2274 else if( s == -1.0 )
2275 return (mpq_cmp(r.dpointer->privatevalue, Rational::NEGONE.dpointer->privatevalue) <= 0);
2286 #ifdef SOPLEX_PERFALT_1 2287 return (mpq_sgn(r.dpointer->privatevalue) == 1);
2289 return (mpq_cmp(r.dpointer->privatevalue, Rational::ZERO.dpointer->privatevalue) > 0);
2292 return (mpq_cmp(r.dpointer->privatevalue, Rational::POSONE.dpointer->privatevalue) > 0);
2293 else if( s == -1.0 )
2294 return (mpq_cmp(r.dpointer->privatevalue, Rational::NEGONE.dpointer->privatevalue) > 0);
2305 #ifdef SOPLEX_PERFALT_1 2306 return (mpq_sgn(r.dpointer->privatevalue) >= 0);
2308 return (mpq_cmp(r.dpointer->privatevalue, Rational::ZERO.dpointer->privatevalue) >= 0);
2311 return (mpq_cmp(r.dpointer->privatevalue, Rational::POSONE.dpointer->privatevalue) >= 0);
2312 else if( s == -1.0 )
2313 return (mpq_cmp(r.dpointer->privatevalue, Rational::NEGONE.dpointer->privatevalue) >= 0);
2372 #ifdef SOPLEX_PERFALT_1 2373 return (mpq_sgn(r.dpointer->privatevalue) == 0);
2375 return (mpq_equal(r.dpointer->privatevalue, Rational::ZERO.dpointer->privatevalue) != 0);
2378 return (mpq_equal(r.dpointer->privatevalue, Rational::POSONE.dpointer->privatevalue) != 0);
2379 else if( s == -1.0 )
2380 return (mpq_equal(r.dpointer->privatevalue, Rational::NEGONE.dpointer->privatevalue) != 0);
2391 #ifdef SOPLEX_PERFALT_1 2392 return (mpq_sgn(r.dpointer->privatevalue) != 0);
2394 return (mpq_equal(r.dpointer->privatevalue, Rational::ZERO.dpointer->privatevalue) == 0);
2397 return (mpq_equal(r.dpointer->privatevalue, Rational::POSONE.dpointer->privatevalue) == 0);
2398 else if( s == -1.0 )
2399 return (mpq_equal(r.dpointer->privatevalue, Rational::NEGONE.dpointer->privatevalue) == 0);
2410 #ifdef SOPLEX_PERFALT_1 2411 return (mpq_sgn(r.dpointer->privatevalue) == -1);
2413 return (mpq_cmp(r.dpointer->privatevalue, Rational::ZERO.dpointer->privatevalue) < 0);
2416 return (mpq_cmp(r.dpointer->privatevalue, Rational::POSONE.dpointer->privatevalue) < 0);
2417 else if( s == -1.0 )
2418 return (mpq_cmp(r.dpointer->privatevalue, Rational::NEGONE.dpointer->privatevalue) < 0);
2429 #ifdef SOPLEX_PERFALT_1 2430 return (mpq_sgn(r.dpointer->privatevalue) <= 0);
2432 return (mpq_cmp(r.dpointer->privatevalue, Rational::ZERO.dpointer->privatevalue) <= 0);
2435 return (mpq_cmp(r.dpointer->privatevalue, Rational::POSONE.dpointer->privatevalue) <= 0);
2436 else if( s == -1.0 )
2437 return (mpq_cmp(r.dpointer->privatevalue, Rational::NEGONE.dpointer->privatevalue) <= 0);
2448 #ifdef SOPLEX_PERFALT_1 2449 return (mpq_sgn(r.dpointer->privatevalue) == 1);
2451 return (mpq_cmp(r.dpointer->privatevalue, Rational::ZERO.dpointer->privatevalue) > 0);
2454 return (mpq_cmp(r.dpointer->privatevalue, Rational::POSONE.dpointer->privatevalue) > 0);
2455 else if( s == -1.0 )
2456 return (mpq_cmp(r.dpointer->privatevalue, Rational::NEGONE.dpointer->privatevalue) > 0);
2467 #ifdef SOPLEX_PERFALT_1 2468 return (mpq_sgn(r.dpointer->privatevalue) >= 0);
2470 return (mpq_cmp(r.dpointer->privatevalue, Rational::ZERO.dpointer->privatevalue) >= 0);
2473 return (mpq_cmp(r.dpointer->privatevalue, Rational::POSONE.dpointer->privatevalue) >= 0);
2474 else if( s == -1.0 )
2475 return (mpq_cmp(r.dpointer->privatevalue, Rational::NEGONE.dpointer->privatevalue) >= 0);
2542 mpq_neg(res.dpointer->privatevalue, res.dpointer->privatevalue);
2553 return Rational::ZERO;
2556 else if( d == -1.0 )
2561 mpq_mul(retval.dpointer->privatevalue, retval.dpointer->privatevalue, r.dpointer->privatevalue);
2572 return Rational::ZERO;
2579 else if( d == -1.0 )
2583 mpq_neg(retval.dpointer->privatevalue, retval.dpointer->privatevalue);
2589 mpq_div(retval.dpointer->privatevalue, retval.dpointer->privatevalue, r.dpointer->privatevalue);
2600 #ifdef SOPLEX_PERFALT_1 2601 return (mpq_sgn(r.dpointer->privatevalue) == 0);
2603 return (mpq_equal(r.dpointer->privatevalue, Rational::ZERO.dpointer->privatevalue) != 0);
2606 return (mpq_equal(r.dpointer->privatevalue, Rational::POSONE.dpointer->privatevalue) != 0);
2608 return (mpq_equal(r.dpointer->privatevalue, Rational::NEGONE.dpointer->privatevalue) != 0);
2619 #ifdef SOPLEX_PERFALT_1 2620 return (mpq_sgn(r.dpointer->privatevalue) != 0);
2622 return (mpq_equal(r.dpointer->privatevalue, Rational::ZERO.dpointer->privatevalue) == 0);
2625 return (mpq_equal(r.dpointer->privatevalue, Rational::POSONE.dpointer->privatevalue) == 0);
2627 return (mpq_equal(r.dpointer->privatevalue, Rational::NEGONE.dpointer->privatevalue) == 0);
2638 #ifdef SOPLEX_PERFALT_1 2639 return (mpq_sgn(r.dpointer->privatevalue) == -1);
2641 return (mpq_cmp(r.dpointer->privatevalue, Rational::ZERO.dpointer->privatevalue) < 0);
2644 return (mpq_cmp(r.dpointer->privatevalue, Rational::POSONE.dpointer->privatevalue) < 0);
2646 return (mpq_cmp(r.dpointer->privatevalue, Rational::NEGONE.dpointer->privatevalue) < 0);
2657 #ifdef SOPLEX_PERFALT_1 2658 return (mpq_sgn(r.dpointer->privatevalue) <= 0);
2660 return (mpq_cmp(r.dpointer->privatevalue, Rational::ZERO.dpointer->privatevalue) <= 0);
2663 return (mpq_cmp(r.dpointer->privatevalue, Rational::POSONE.dpointer->privatevalue) <= 0);
2665 return (mpq_cmp(r.dpointer->privatevalue, Rational::NEGONE.dpointer->privatevalue) <= 0);
2676 #ifdef SOPLEX_PERFALT_1 2677 return (mpq_sgn(r.dpointer->privatevalue) == 1);
2679 return (mpq_cmp(r.dpointer->privatevalue, Rational::ZERO.dpointer->privatevalue) > 0);
2682 return (mpq_cmp(r.dpointer->privatevalue, Rational::POSONE.dpointer->privatevalue) > 0);
2684 return (mpq_cmp(r.dpointer->privatevalue, Rational::NEGONE.dpointer->privatevalue) > 0);
2695 #ifdef SOPLEX_PERFALT_1 2696 return (mpq_sgn(r.dpointer->privatevalue) >= 0);
2698 return (mpq_cmp(r.dpointer->privatevalue, Rational::ZERO.dpointer->privatevalue) >= 0);
2701 return (mpq_cmp(r.dpointer->privatevalue, Rational::POSONE.dpointer->privatevalue) >= 0);
2703 return (mpq_cmp(r.dpointer->privatevalue, Rational::NEGONE.dpointer->privatevalue) >= 0);
2770 mpq_neg(res.dpointer->privatevalue, res.dpointer->privatevalue);
2781 return Rational::ZERO;
2789 mpq_mul(retval.dpointer->privatevalue, retval.dpointer->privatevalue, r.dpointer->privatevalue);
2800 return Rational::ZERO;
2811 mpq_neg(retval.dpointer->privatevalue, retval.dpointer->privatevalue);
2817 mpq_div(retval.dpointer->privatevalue, retval.dpointer->privatevalue, r.dpointer->privatevalue);
2828 mpq_abs(res.dpointer->privatevalue, r.dpointer->privatevalue);
2837 return mpq_sgn(r.dpointer->privatevalue);
2846 mpq_neg(res.dpointer->privatevalue, r.dpointer->privatevalue);
2855 assert(vector != 0);
2856 assert(length >= 0);
2861 for(
int i = 0; i < length; i++ )
2872 assert(vector != 0);
2873 assert(length >= 0);
2878 mpz_init_set_ui(lcm, 1);
2880 for(
int i = 0; i < length; i++ )
2881 mpz_lcm(lcm, lcm, mpq_denref(vector[i].getMpqRef()));
2883 int size = (int)mpz_sizeinbase(lcm, base);
2895 assert(vector != 0);
2896 assert(length >= 0);
2901 for(
int i = 0; i < length; i++ )
2903 size_t dsize = mpz_sizeinbase(mpq_denref(vector[i].getMpqRef()), base);
2966 this->privatevalue = r;
2973 this->privatevalue = (
long double)(r);
2980 this->privatevalue = (
long double)(i);
3110 Rational::operator double()
const 3118 Rational::operator
long double()
const 3436 return sizeof(
long double);
3453 std::stringstream sstream;
3454 sstream << std::setprecision(precision <= 0 ? 16 : precision) << r;
3455 return sstream.str();
3941 assert(vector != 0);
3942 assert(length >= 0);
3947 for(
int i = 0; i < length; i++ )
3958 assert(vector != 0);
3959 assert(length >= 0);
3970 assert(vector != 0);
3971 assert(length >= 0);
3979 #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