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.
Rational ratFromString(const char *desc)
int dlcmSizeRational(const Rational *vector, const int length, const int base)
Size of least common multiple of denominators in rational vector.
void SpxGcd(Integer &result, Integer a, Integer b)
number< gmp_int, et_off > Integer
VectorBase< R > operator-(const SVectorBase< R > &v, const VectorBase< R > &w)
Subtraction.
bool isAdjacentTo(const Rational &r, const double &d)
std::ostream & operator<<(std::ostream &s, const VectorBase< R > &vec)
Output operator.
int totalSizeRational(const Rational *vector, const int length, const int base)
Total size of rational vector.
static std::string::const_iterator findSubStringIC(const std::string &substr, const std::string &str)
number< gmp_rational, et_off > Rational
DSVectorBase< R > operator*(const SVectorBase< R > &v, R x)
Scaling.
void powRound(Rational &r)
round up to next power of two
void printInteger(Integer r)
void printRational(Rational r)
int sizeInBase(const Rational R, const int base)
Size in specified base (bit size for base 2)
int orderOfMagnitude(Rational &r)
returns the order of magnitude of the given rational
int dmaxSizeRational(const Rational *vector, const int length, const int base)
Size of largest denominator in rational vector.
void SpxLcm(Integer &result, Integer a, Integer b)
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.