8#ifndef __SOPLEX_MULTIPRECISION_HPP_
9#define __SOPLEX_MULTIPRECISION_HPP_
19#ifdef SOPLEX_WITH_BOOST
20#include <boost/multiprecision/number.hpp>
23#include <boost/multiprecision/gmp.hpp>
28using namespace boost::multiprecision;
33 mpz_lcm(result.backend().data(), a.backend().data(), b.backend().data());
37 mpz_gcd(result.backend().data(), a.backend().data(), b.backend().data());
42#include <boost/multiprecision/cpp_int.hpp>
43#include <boost/multiprecision/detail/default_ops.hpp>
48using namespace boost::multiprecision;
53 result = boost::multiprecision::lcm(a, b);
57 result = boost::multiprecision::gcd(a, b);
68 std::cout << r << std::endl;
73 std::cout << r << std::endl;
77 double x = (double) r;
89 b = (double)nextafter(a, 1e100);
95 a = (double)nextafter(b, -1e100);
98 return ((a == d) || (b == d));
103 r =
Rational(denominator(r), numerator(r));
114 den = denominator(r);
115 roundval = num / den;
117 size_t binlog = roundval == 0 ? 1 : msb(roundval) + 1;
120 roundval = boost::multiprecision::pow(base, (
unsigned int)binlog);
128 if(numerator(r) == 0 || (
int) log10((
double)numerator(r)) == log10((
double)denominator(r)))
131 return (
int) log10((
double)numerator(r)) - (int) log10((
double)denominator(r));
136std::string::const_iterator
findSubStringIC(
const std::string& substr,
const std::string& str)
138 auto it = std::search(
139 str.begin(), str.end(),
140 substr.begin(), substr.end(),
141 [](
char ch1,
char ch2)
143 return std::toupper(ch1) == std::toupper(ch2);
153 if(0 == strcmp(desc,
"inf"))
157 else if(0 == strcmp(desc,
"-inf"))
166 if(s.find_first_of(
".Ee") == std::string::npos)
181 int exponentidx = int(it - s.begin());
182 mult = std::stoi(s.substr(exponentidx + 1, s.length()));
183 s = s.substr(0, exponentidx);
190 size_t pos = s.find(
'.');
193 if(pos != std::string::npos)
195 size_t exp = s.length() - 1 - pos;
196 std::string den(
"1");
198 for(
size_t i = 0; i < exp; ++i)
202 assert(std::all_of(s.begin() + 1, s.end(), ::isdigit));
206 s.erase(1,
SOPLEX_MIN(s.substr(1).find_first_not_of(
'0'), s.size() - 1));
208 s.erase(0,
SOPLEX_MIN(s.find_first_not_of(
'0'), s.size() - 1));
219 res *= pow(10, mult);
229#ifndef SOPLEX_WITH_GMP
244 inline void rationalErrorMessage()
const
246 SPX_MSG_ERROR(std::cerr <<
"Using rational methods without linking boost is not supported" <<
259 inline Rational(
const long double& r)
278#ifdef SOPLEX_WITH_BOOST
280 inline template <
typename T, boost::multiprecision::expression_
template_option eto>
281 Rational(
const boost::multiprecision::number<T, eto>& q)
296 inline Rational& operator=(
const long double& r)
301 inline Rational& operator=(
const double& r)
306 inline Rational& operator=(
const int& i)
311 inline Rational& operator=(
const mpq_t& q)
318 rationalErrorMessage();
320 inline void assign(
const long double& r)
322 rationalErrorMessage();
324 inline void assign(
const double& r)
326 rationalErrorMessage();
328 inline void assign(
const int& i)
330 rationalErrorMessage();
336 inline operator double()
const
340 inline operator long double()
const
344 inline operator float()
const
348#ifdef SOPLEX_WITH_BOOST
349#ifndef SOPLEX_WITH_CPPMPF
351 inline template <
typename T, boost::multiprecision::expression_
template_option eto>
352 operator boost::multiprecision::number<T, eto>()
const
354 rationalErrorMessage();
359 inline template <
unsigned bits, boost::multiprecision::expression_
template_option eto>
360 operator boost::multiprecision::number<boost::multiprecision::backends::cpp_dec_float<bits>, eto>()
363 rationalErrorMessage();
381 rationalErrorMessage();
387 rationalErrorMessage();
391 inline Rational operator+(
const double& r)
const
393 rationalErrorMessage();
397 inline Rational operator+=(
const double& r)
399 rationalErrorMessage();
403 inline Rational operator+(
const int& r)
const
405 rationalErrorMessage();
409 inline Rational operator+=(
const int& r)
411 rationalErrorMessage();
417 rationalErrorMessage();
423 rationalErrorMessage();
429 rationalErrorMessage();
433 inline Rational operator-=(
const double& r)
435 rationalErrorMessage();
441 rationalErrorMessage();
445 inline Rational operator-=(
const int& r)
447 rationalErrorMessage();
453 rationalErrorMessage();
459 rationalErrorMessage();
465 rationalErrorMessage();
469 inline Rational operator*=(
const double& r)
471 rationalErrorMessage();
477 rationalErrorMessage();
481 inline Rational operator*=(
const int& r)
483 rationalErrorMessage();
489 rationalErrorMessage();
495 rationalErrorMessage();
499 inline Rational operator/(
const double& r)
const
501 rationalErrorMessage();
505 inline Rational operator/=(
const double& r)
507 rationalErrorMessage();
511 inline Rational operator/(
const int& r)
const
513 rationalErrorMessage();
517 inline Rational operator/=(
const int& r)
519 rationalErrorMessage();
525 rationalErrorMessage();
532 rationalErrorMessage();
539 rationalErrorMessage();
546 rationalErrorMessage();
559 rationalErrorMessage();
572 rationalErrorMessage();
583 r.rationalErrorMessage();
586 inline std::string str()
const
588 this->rationalErrorMessage();
589 return std::string(
"");
598 r.rationalErrorMessage();
603 r.rationalErrorMessage();
608 r.rationalErrorMessage();
613 r.rationalErrorMessage();
618 r.rationalErrorMessage();
623 r.rationalErrorMessage();
628 r.rationalErrorMessage();
632 inline friend bool operator!=(
const Rational& r,
const double& s)
634 r.rationalErrorMessage();
637 inline friend bool operator==(
const Rational& r,
const double& s)
639 r.rationalErrorMessage();
642 inline friend bool operator<(
const Rational& r,
const double& s)
644 r.rationalErrorMessage();
647 inline friend bool operator<=(
const Rational& r,
const double& s)
649 r.rationalErrorMessage();
652 inline friend bool operator>(
const Rational& r,
const double& s)
654 r.rationalErrorMessage();
657 inline friend bool operator>=(
const Rational& r,
const double& s)
659 r.rationalErrorMessage();
663 inline friend bool operator!=(
const double& r,
const Rational& s)
665 s.rationalErrorMessage();
668 inline friend bool operator==(
const double& r,
const Rational& s)
670 s.rationalErrorMessage();
673 inline friend bool operator<(
const double& r,
const Rational& s)
675 s.rationalErrorMessage();
678 inline friend bool operator<=(
const double& r,
const Rational& s)
680 s.rationalErrorMessage();
683 inline friend bool operator>(
const double& r,
const Rational& s)
685 s.rationalErrorMessage();
688 inline friend bool operator>=(
const double& r,
const Rational& s)
690 s.rationalErrorMessage();
694 inline friend bool operator!=(
const Rational& r,
const long double& s)
696 r.rationalErrorMessage();
699 inline friend bool operator==(
const Rational& r,
const long double& s)
701 r.rationalErrorMessage();
704 inline friend bool operator<(
const Rational& r,
const long double& s)
706 r.rationalErrorMessage();
709 inline friend bool operator<=(
const Rational& r,
const long double& s)
711 r.rationalErrorMessage();
714 inline friend bool operator>(
const Rational& r,
const long double& s)
716 r.rationalErrorMessage();
719 inline friend bool operator>=(
const Rational& r,
const long double& s)
721 r.rationalErrorMessage();
725 inline friend bool operator!=(
const long double& r,
const Rational& s)
727 s.rationalErrorMessage();
730 inline friend bool operator==(
const long double& r,
const Rational& s)
732 s.rationalErrorMessage();
735 inline friend bool operator<(
const long double& r,
const Rational& s)
737 s.rationalErrorMessage();
740 inline friend bool operator<=(
const long double& r,
const Rational& s)
742 s.rationalErrorMessage();
745 inline friend bool operator>(
const long double& r,
const Rational& s)
747 s.rationalErrorMessage();
750 inline friend bool operator>=(
const long double& r,
const Rational& s)
752 s.rationalErrorMessage();
756 inline friend bool operator!=(
const Rational& r,
const float& s)
758 r.rationalErrorMessage();
761 inline friend bool operator==(
const Rational& r,
const float& s)
763 r.rationalErrorMessage();
766 inline friend bool operator<(
const Rational& r,
const float& s)
768 r.rationalErrorMessage();
771 inline friend bool operator<=(
const Rational& r,
const float& s)
773 r.rationalErrorMessage();
776 inline friend bool operator>(
const Rational& r,
const float& s)
778 r.rationalErrorMessage();
781 inline friend bool operator>=(
const Rational& r,
const float& s)
783 r.rationalErrorMessage();
787 inline friend bool operator!=(
const float& r,
const Rational& s)
789 s.rationalErrorMessage();
792 inline friend bool operator==(
const float& r,
const Rational& s)
794 s.rationalErrorMessage();
797 inline friend bool operator<(
const float& r,
const Rational& s)
799 s.rationalErrorMessage();
802 inline friend bool operator<=(
const float& r,
const Rational& s)
804 s.rationalErrorMessage();
807 inline friend bool operator>(
const float& r,
const Rational& s)
809 s.rationalErrorMessage();
812 inline friend bool operator>=(
const float& r,
const Rational& s)
814 s.rationalErrorMessage();
820 r.rationalErrorMessage();
825 r.rationalErrorMessage();
830 r.rationalErrorMessage();
835 r.rationalErrorMessage();
839 inline friend bool operator!=(
const Rational& r,
const int& s)
841 r.rationalErrorMessage();
844 inline friend bool operator==(
const Rational& r,
const int& s)
846 r.rationalErrorMessage();
849 inline friend bool operator<(
const Rational& r,
const int& s)
851 r.rationalErrorMessage();
854 inline friend bool operator<=(
const Rational& r,
const int& s)
856 r.rationalErrorMessage();
859 inline friend bool operator>(
const Rational& r,
const int& s)
861 r.rationalErrorMessage();
864 inline friend bool operator>=(
const Rational& r,
const int& s)
866 r.rationalErrorMessage();
870 inline friend bool operator!=(
const int& r,
const Rational& s)
872 s.rationalErrorMessage();
875 inline friend bool operator==(
const int& r,
const Rational& s)
877 s.rationalErrorMessage();
880 inline friend bool operator<(
const int& r,
const Rational& s)
882 s.rationalErrorMessage();
885 inline friend bool operator<=(
const int& r,
const Rational& s)
887 s.rationalErrorMessage();
890 inline friend bool operator>(
const int& r,
const Rational& s)
892 s.rationalErrorMessage();
895 inline friend bool operator>=(
const int& r,
const Rational& s)
897 s.rationalErrorMessage();
903 r.rationalErrorMessage();
908 r.rationalErrorMessage();
913 r.rationalErrorMessage();
918 r.rationalErrorMessage();
924 r.rationalErrorMessage();
927 inline friend int sign(
const Rational& r)
929 r.rationalErrorMessage();
934 q.rationalErrorMessage();
942 r.rationalErrorMessage();
947 r.rationalErrorMessage();
956 r.rationalErrorMessage();
964 r.rationalErrorMessage();
968 r.rationalErrorMessage();
978#ifndef SOPLEX_WITH_BOOST
979 SPX_MSG_ERROR(std::cerr <<
"ERROR: rational solve without Boost not defined!" << std::endl;)
988 size_t numsize, densize;
990#ifdef SOPLEX_WITH_GMP
991 densize = mpz_sizeinbase(den.backend().data(), base);
992 numsize = mpz_sizeinbase(num.backend().data(), base);
997 densize = (size_t)(log2(den.convert_to<
double>()) / log2(
double(base))) + 1;
998 numsize = (size_t)(log2(num.convert_to<
double>()) / log2(
double(base))) + 1;
1002 densize = msb(den) + 1;
1003 numsize = msb(num) + 1;
1008 return (
int)(densize + numsize);
1014 assert(vector !=
nullptr);
1015 assert(length >= 0);
1020 for(
int i = 0; i < length; i++)
1029 assert(vector !=
nullptr);
1030 assert(length >= 0);
1032#ifndef SOPLEX_WITH_BOOST
1033 SPX_MSG_ERROR(std::cerr <<
"ERROR: rational solve without Boost not defined!" << std::endl;)
1039 for(
int i = 0; i < length; i++)
1040 SpxLcm(lcm, lcm, denominator(vector[i]));
1051 assert(vector !=
nullptr);
1052 assert(length >= 0);
1053#ifndef SOPLEX_WITH_BOOST
1054 SPX_MSG_ERROR(std::cerr <<
"ERROR: rational solve without Boost not defined!" << std::endl;)
1060 for(
int i = 0; i < length; i++)
Everything should be within this namespace.
int orderOfMagnitude(Rational &r)
returns the order of magnitude of the given rational
number< gmp_int, et_off > Integer
std::ostream & operator<<(std::ostream &s, const VectorBase< R > &vec)
Output operator.
void powRound(Rational &r)
round up to next power of two
VectorBase< R > operator-(const SVectorBase< R > &v, const VectorBase< R > &w)
Subtraction.
int dmaxSizeRational(const Rational *vector, const int length, const int base)
Size of largest denominator in rational vector.
DSVectorBase< R > operator*(const SVectorBase< R > &v, R x)
Scaling.
number< gmp_rational, et_off > Rational
int dlcmSizeRational(const Rational *vector, const int length, const int base)
Size of least common multiple of denominators in rational vector.
bool isAdjacentTo(const Rational &r, const double &d)
int sizeInBase(const Rational R, const int base)
Size in specified base (bit size for base 2)
void printInteger(Integer r)
void SpxLcm(Integer &result, Integer a, Integer b)
void SpxGcd(Integer &result, Integer a, Integer b)
static std::string::const_iterator findSubStringIC(const std::string &substr, const std::string &str)
Rational ratFromString(const char *desc)
int totalSizeRational(const Rational *vector, const int length, const int base)
Total size of rational vector.
void printRational(Rational r)
Debugging, floating point type and parameter definitions.
#define SPX_MSG_ERROR(x)
Prints out message x if the verbosity level is at least SPxOut::ERROR.