1
2 /* ----------------------------------------------------------------------
3 * This file is autogenerated from the file multiprecision.hpp.in during
4 * the cmake configuration of your project. If you need to make changes
5 * edit the original file.
6 * ----------------------------------------------------------------------
7 */
8 #ifndef __SOPLEX_MULTIPRECISION_HPP_
9 #define __SOPLEX_MULTIPRECISION_HPP_
10 #include <numeric>
11 #include <vector>
12 #include <string>
13 #include "soplex/spxdefines.h"
14
15 #ifdef SOPLEX_WITH_GMP
16 #include <gmp.h>
17 #endif
18
19 #ifdef SOPLEX_WITH_BOOST
20 #include <boost/multiprecision/number.hpp>
21
22 #ifdef SOPLEX_WITH_GMP
23 #include <boost/multiprecision/gmp.hpp>
24
25 namespace soplex
26 {
27
28 using namespace boost::multiprecision;
29 using Rational = number<gmp_rational, et_off>;
30 using Integer = number<gmp_int, et_off>;
31 inline void SpxLcm(Integer& result, Integer a, Integer b)
32 {
33 mpz_lcm(result.backend().data(), a.backend().data(), b.backend().data());
34 }
35 inline void SpxGcd(Integer& result, Integer a, Integer b)
36 {
37 mpz_gcd(result.backend().data(), a.backend().data(), b.backend().data());
38 }
39
40 } // namespace soplex
41 #else
42 #include <boost/multiprecision/cpp_int.hpp>
43 #include <boost/multiprecision/detail/default_ops.hpp>
44
45 namespace soplex
46 {
47
48 using namespace boost::multiprecision;
49 using Rational = cpp_rational;
50 using Integer = cpp_int;
51 inline void SpxLcm(Integer& result, Integer a, Integer b)
52 {
53 result = boost::multiprecision::lcm(a, b);
54 }
55 inline void SpxGcd(Integer& result, Integer a, Integer b)
56 {
57 result = boost::multiprecision::gcd(a, b);
58 }
59
60 } // namespace soplex
61 #endif
62
63 namespace soplex
64 {
65
66 inline void printRational(Rational r)
67 {
68 std::cout << r << std::endl;
69 }
70
71 inline void printInteger(Integer r)
72 {
73 std::cout << r << std::endl;
74 }
75 inline bool isAdjacentTo(const Rational& r, const double& d)
76 {
77 double x = (double) r;
78 double a;
79 double b;
80 Rational tmp = x;
81
82 // the rational value is representable in double precision
83 if(tmp == r)
84 return true;
85 // the rounded value is smaller than the rational value
86 else if(tmp < r)
87 {
88 a = x;
89 b = (double)nextafter(a, 1e100);
90 }
91 // the rounded value is larger than the rational value
92 else
93 {
94 b = x;
95 a = (double)nextafter(b, -1e100);
96 }
97
98 return ((a == d) || (b == d));
99 }
100
101 inline void invert(Rational& r)
102 {
103 r = Rational(denominator(r), numerator(r));
104 }
105
106 /// round up to next power of two
107 inline void powRound(Rational& r)
108 {
109 Integer roundval;
110 Integer den;
111 Integer num;
112
113 num = numerator(r);
114 den = denominator(r);
115 roundval = num / den;
116
117 size_t binlog = roundval == 0 ? 1 : msb(roundval) + 1;
118 Integer base = 2;
119
120 roundval = boost::multiprecision::pow(base, (unsigned int)binlog);
121
122 r = roundval;
123 }
124
125 /// returns the order of magnitude of the given rational
126 inline int orderOfMagnitude(Rational& r)
127 {
128 if(numerator(r) == 0 || (int) log10((double)numerator(r)) == log10((double)denominator(r)))
129 return 0;
130 else
131 return (int) log10((double)numerator(r)) - (int) log10((double)denominator(r));
132 }
133
134 /* find substring, ignore case */
135 static
136 std::string::const_iterator findSubStringIC(const std::string& substr, const std::string& str)
137 {
138 auto it = std::search(
139 str.begin(), str.end(),
140 substr.begin(), substr.end(),
141 [](char ch1, char ch2)
142 {
143 return std::toupper(ch1) == std::toupper(ch2);
144 }
145 );
146 return it;
147 }
148
149 inline Rational ratFromString(const char* desc)
150 {
151 Rational res;
152
153 if(0 == strcmp(desc, "inf"))
154 {
155 res = 1e100;
156 }
157 else if(0 == strcmp(desc, "-inf"))
158 {
159 res = -1e100;
160 }
161 else
162 {
163 std::string s(desc);
164
165 /* case 1: string is given in nom/den format */
166 if(s.find_first_of(".Ee") == std::string::npos)
167 {
168 if(s[0] == '+')
169 res = Rational(desc + 1);
170 else
171 res = Rational(desc);
172 }
173 /* case 2: string is given as base-10 decimal number */
174 else
175 {
176 std::string::const_iterator it = findSubStringIC("e", s);
177 int mult = 0;
178
179 if(it != s.end())
180 {
181 int exponentidx = int(it - s.begin());
182 mult = std::stoi(s.substr(exponentidx + 1, s.length()));
183 s = s.substr(0, exponentidx);
184 }
185
186 // std::cout << s << std::endl;
187 if(s[0] == '.')
188 s.insert(0, "0");
189
190 size_t pos = s.find('.');
191
192 // if s contains a ., convert it to a rational
193 if(pos != std::string::npos)
194 {
195 size_t exp = s.length() - 1 - pos;
196 std::string den("1");
197
198 for(size_t i = 0; i < exp; ++i)
199 den.append("0");
200
201 s.erase(pos, 1);
202 assert(std::all_of(s.begin() + 1, s.end(), ::isdigit));
203
204 // remove padding 0s
205 if(s[0] == '-')
206 s.erase(1, SOPLEX_MIN(s.substr(1).find_first_not_of('0'), s.size() - 1));
207 else
208 s.erase(0, SOPLEX_MIN(s.find_first_not_of('0'), s.size() - 1));
209
210 s.append("/");
211 s.append(den);
212 }
213
214 res = Rational(s);
215 res *= pow(10, mult);
216 }
217 }
218
219 return res;
220 }
221
222 } // namespace soplex
223 #else
224
225 #ifndef SOPLEX_WITH_GMP
226 using mpq_t = char;
227 #endif
228
229 using Integer = int;
230 // this is a placeholder class to ensure compilation when boost ist not linked. Rationals need BOOST in order to function.
231 class Rational
232 {
233
234 public:
235
236 ///@name Construction and destruction
237 ///@{
238
239 inline void rationalErrorMessage() const
240 {
241 SPX_MSG_ERROR(std::cerr << "Using rational methods without linking boost is not supported" <<
242 std::endl;)
243 };
244
245 /// default constructor
246 inline Rational()
247 {
248 };
249 /// copy constructor
250 inline Rational(const Rational& r)
251 {
252 };
253 /// constructor from long double
254 inline Rational(const long double& r)
255 {
256 };
257 /// constructor from double
258 inline Rational(const double& r)
259 {
260 };
261 ///constructor from int
262 inline Rational(const int& i)
263 {
264 };
265 /// constructor from Integer
266 inline Rational(const Integer& num, const Integer& den)
267 {
268 };
269 /// constructor from mpq_t (GMP only)
270 inline Rational(const mpq_t& q)
271 {
272 };
273 #ifdef SOPLEX_WITH_BOOST
274 // constructor from boost number
275 inline template <typename T, boost::multiprecision::expression_template_option eto>
276 Rational(const boost::multiprecision::number<T, eto>& q)
277 {
278 };
279 #endif
280 /// destructor
281 inline ~Rational()
282 {
283 };
284
285 /// assignment operator
286 inline Rational& operator=(const Rational&)
287 {
288 return *this;
289 };
290 /// assignment operator from long double
291 inline Rational& operator=(const long double& r)
292 {
293 return *this;
294 };
295 /// assignment operator from double
296 inline Rational& operator=(const double& r)
297 {
298 return *this;
299 };
300 /// assignment operator from int
301 inline Rational& operator=(const int& i)
302 {
303 return *this;
304 };
305 /// assignment operator from mpq_t
306 inline Rational& operator=(const mpq_t& q)
307 {
308 return *this;
309 };
310
311 inline void assign(const Rational&)
312 {
313 rationalErrorMessage();
314 };
315 inline void assign(const long double& r)
316 {
317 rationalErrorMessage();
318 };
319 inline void assign(const double& r)
320 {
321 rationalErrorMessage();
322 };
323 inline void assign(const int& i)
324 {
325 rationalErrorMessage();
326 };
327
328 ///@name Typecasts
329 ///@{
330
331 inline operator double() const
332 {
333 return 0;
334 };
335 inline operator long double() const
336 {
337 return 0;
338 };
339 inline operator float() const
340 {
341 return 0;
342 };
343 #ifdef SOPLEX_WITH_BOOST
344 #ifndef SOPLEX_WITH_CPPMPF
345 // Operator to typecast Rational to one of the Boost Number types
346 inline template <typename T, boost::multiprecision::expression_template_option eto>
347 operator boost::multiprecision::number<T, eto>() const
348 {
349 rationalErrorMessage();
350 return 0;
351 };
352 #else
353 // Operator to typecast Rational to one of the Boost Number types
354 inline template <unsigned bits, boost::multiprecision::expression_template_option eto>
355 operator boost::multiprecision::number<boost::multiprecision::backends::cpp_dec_float<bits>, eto>()
356 const
357 {
358 rationalErrorMessage();
359 return 0;
360 };
361 #endif
362 #endif
363
364 ///@name Typecasts
365 ///@{
366
367 ///@}
368
369
370 ///@name Arithmetic operators
371 ///@{
372
373 /// addition operator
374 inline Rational operator+(const Rational& r) const
375 {
376 rationalErrorMessage();
377 return *this;
378 }
379 /// addition assignment operator
380 inline Rational operator+=(const Rational& r)
381 {
382 rationalErrorMessage();
383 return *this;
384 }
385 /// addition operator for doubles
386 inline Rational operator+(const double& r) const
387 {
388 rationalErrorMessage();
389 return *this;
390 }
391 /// addition assignment operator for doubles
392 inline Rational operator+=(const double& r)
393 {
394 rationalErrorMessage();
395 return *this;
396 }
397 /// addition operator for ints
398 inline Rational operator+(const int& r) const
399 {
400 rationalErrorMessage();
401 return *this;
402 }
403 /// addition assignment operator for ints
404 inline Rational operator+=(const int& r)
405 {
406 rationalErrorMessage();
407 return *this;
408 }
409 /// subtraction operator
410 inline Rational operator-(const Rational& r) const
411 {
412 rationalErrorMessage();
413 return *this;
414 }
415 /// subtraction assignment operator
416 inline Rational operator-=(const Rational& r)
417 {
418 rationalErrorMessage();
419 return *this;
420 }
421 /// subtraction operator for doubles
422 inline Rational operator-(const double& r) const
423 {
424 rationalErrorMessage();
425 return *this;
426 }
427 /// subtraction assignment operator for doubles
428 inline Rational operator-=(const double& r)
429 {
430 rationalErrorMessage();
431 return *this;
432 }
433 /// subtraction operator for ints
434 inline Rational operator-(const int& r) const
435 {
436 rationalErrorMessage();
437 return *this;
438 }
439 /// subtraction assignment operator for ints
440 inline Rational operator-=(const int& r)
441 {
442 rationalErrorMessage();
443 return *this;
444 }
445 /// multiplication operator
446 inline Rational operator*(const Rational& r) const
447 {
448 rationalErrorMessage();
449 return *this;
450 }
451 /// multiplication assignment operator operator
452 inline Rational operator*=(const Rational& r)
453 {
454 rationalErrorMessage();
455 return *this;
456 }
457 /// multiplication operator for doubles
458 inline Rational operator*(const double& r) const
459 {
460 rationalErrorMessage();
461 return *this;
462 }
463 /// multiplication assignment operator for doubles
464 inline Rational operator*=(const double& r)
465 {
466 rationalErrorMessage();
467 return *this;
468 }
469 /// multiplication operator for ints
470 inline Rational operator*(const int& r) const
471 {
472 rationalErrorMessage();
473 return *this;
474 }
475 /// multiplication assignment operator for ints
476 inline Rational operator*=(const int& r)
477 {
478 rationalErrorMessage();
479 return *this;
480 }
481 /// division operator
482 inline Rational operator/(const Rational& r) const
483 {
484 rationalErrorMessage();
485 return *this;
486 }
487 /// division assignment operator
488 inline Rational operator/=(const Rational& r)
489 {
490 rationalErrorMessage();
491 return *this;
492 }
493 /// division operator for doubles
494 inline Rational operator/(const double& r) const
495 {
496 rationalErrorMessage();
497 return *this;
498 }
499 /// division assignment operator for doubles
500 inline Rational operator/=(const double& r)
501 {
502 rationalErrorMessage();
503 return *this;
504 }
505 /// division operator for ints
506 inline Rational operator/(const int& r) const
507 {
508 rationalErrorMessage();
509 return *this;
510 }
511 /// division assignment operator for ints
512 inline Rational operator/=(const int& r)
513 {
514 rationalErrorMessage();
515 return *this;
516 }
517 /// add product of two rationals
518 Rational& addProduct(const Rational& r, const Rational& s)
519 {
520 rationalErrorMessage();
521 return *this;
522 }
523
524 /// subtract product of two rationals
525 Rational& subProduct(const Rational& r, const Rational& s)
526 {
527 rationalErrorMessage();
528 return *this;
529 }
530
531 /// add quotient of two rationals, r divided by s
532 Rational& addQuotient(const Rational& r, const Rational& s)
533 {
534 rationalErrorMessage();
535 return *this;
536 }
537
538 /// subtract quotient of two rationals, r divided by s
539 Rational& subQuotient(const Rational& r, const Rational& s)
540 {
541 rationalErrorMessage();
542 return *this;
543 }
544
545 ///@}
546
547
548 ///@name Methods for checking exactness of doubles
549 ///@{
550
551 /// checks if \p d is exactly equal to the Rational and if not, if it is one of the two adjacent doubles
552 inline bool isAdjacentTo(const double& d) const
553 {
554 rationalErrorMessage();
555 return false;
556 };
557
558 ///@}
559
560
561 ///@name Methods for querying size
562 ///@{
563
564 /// Size in specified base (bit size for base 2)
565 int sizeInBase(const int base = 2) const
566 {
567 rationalErrorMessage();
568 return 0;
569 };
570
571 ///@}
572
573
574 ///@name Conversion from and to String
575 ///@{
576 inline friend std::ostream& operator<<(std::ostream& os, const Rational& r)
577 {
578 r.rationalErrorMessage();
579 return os;
580 };
581 inline std::string str() const
582 {
583 this->rationalErrorMessage();
584 return std::string("");
585 };
586 ///@}
587
588 ///@name Friends
589 ///@{
590
591 inline friend int compareRational(const Rational& r, const Rational& s)
592 {
593 r.rationalErrorMessage();
594 return 0;
595 };
596 inline friend bool operator!=(const Rational& r, const Rational& s)
597 {
598 r.rationalErrorMessage();
599 return false;
600 };
601 inline friend bool operator==(const Rational& r, const Rational& s)
602 {
603 r.rationalErrorMessage();
604 return false;
605 };
606 inline friend bool operator<(const Rational& r, const Rational& s)
607 {
608 r.rationalErrorMessage();
609 return false;
610 };
611 inline friend bool operator<=(const Rational& r, const Rational& s)
612 {
613 r.rationalErrorMessage();
614 return false;
615 };
616 inline friend bool operator>(const Rational& r, const Rational& s)
617 {
618 r.rationalErrorMessage();
619 return false;
620 };
621 inline friend bool operator>=(const Rational& r, const Rational& s)
622 {
623 r.rationalErrorMessage();
624 return false;
625 };
626
627 inline friend bool operator!=(const Rational& r, const double& s)
628 {
629 r.rationalErrorMessage();
630 return false;
631 };
632 inline friend bool operator==(const Rational& r, const double& s)
633 {
634 r.rationalErrorMessage();
635 return false;
636 };
637 inline friend bool operator<(const Rational& r, const double& s)
638 {
639 r.rationalErrorMessage();
640 return false;
641 };
642 inline friend bool operator<=(const Rational& r, const double& s)
643 {
644 r.rationalErrorMessage();
645 return false;
646 };
647 inline friend bool operator>(const Rational& r, const double& s)
648 {
649 r.rationalErrorMessage();
650 return false;
651 };
652 inline friend bool operator>=(const Rational& r, const double& s)
653 {
654 r.rationalErrorMessage();
655 return false;
656 };
657
658 inline friend bool operator!=(const double& r, const Rational& s)
659 {
660 s.rationalErrorMessage();
661 return false;
662 };
663 inline friend bool operator==(const double& r, const Rational& s)
664 {
665 s.rationalErrorMessage();
666 return false;
667 };
668 inline friend bool operator<(const double& r, const Rational& s)
669 {
670 s.rationalErrorMessage();
671 return false;
672 };
673 inline friend bool operator<=(const double& r, const Rational& s)
674 {
675 s.rationalErrorMessage();
676 return false;
677 };
678 inline friend bool operator>(const double& r, const Rational& s)
679 {
680 s.rationalErrorMessage();
681 return false;
682 };
683 inline friend bool operator>=(const double& r, const Rational& s)
684 {
685 s.rationalErrorMessage();
686 return false;
687 };
688
689 inline friend bool operator!=(const Rational& r, const long double& s)
690 {
691 r.rationalErrorMessage();
692 return false;
693 };
694 inline friend bool operator==(const Rational& r, const long double& s)
695 {
696 r.rationalErrorMessage();
697 return false;
698 };
699 inline friend bool operator<(const Rational& r, const long double& s)
700 {
701 r.rationalErrorMessage();
702 return false;
703 };
704 inline friend bool operator<=(const Rational& r, const long double& s)
705 {
706 r.rationalErrorMessage();
707 return false;
708 };
709 inline friend bool operator>(const Rational& r, const long double& s)
710 {
711 r.rationalErrorMessage();
712 return false;
713 };
714 inline friend bool operator>=(const Rational& r, const long double& s)
715 {
716 r.rationalErrorMessage();
717 return false;
718 };
719
720 inline friend bool operator!=(const long double& r, const Rational& s)
721 {
722 s.rationalErrorMessage();
723 return false;
724 };
725 inline friend bool operator==(const long double& r, const Rational& s)
726 {
727 s.rationalErrorMessage();
728 return false;
729 };
730 inline friend bool operator<(const long double& r, const Rational& s)
731 {
732 s.rationalErrorMessage();
733 return false;
734 };
735 inline friend bool operator<=(const long double& r, const Rational& s)
736 {
737 s.rationalErrorMessage();
738 return false;
739 };
740 inline friend bool operator>(const long double& r, const Rational& s)
741 {
742 s.rationalErrorMessage();
743 return false;
744 };
745 inline friend bool operator>=(const long double& r, const Rational& s)
746 {
747 s.rationalErrorMessage();
748 return false;
749 };
750
751 inline friend bool operator!=(const Rational& r, const float& s)
752 {
753 r.rationalErrorMessage();
754 return false;
755 };
756 inline friend bool operator==(const Rational& r, const float& s)
757 {
758 r.rationalErrorMessage();
759 return false;
760 };
761 inline friend bool operator<(const Rational& r, const float& s)
762 {
763 r.rationalErrorMessage();
764 return false;
765 };
766 inline friend bool operator<=(const Rational& r, const float& s)
767 {
768 r.rationalErrorMessage();
769 return false;
770 };
771 inline friend bool operator>(const Rational& r, const float& s)
772 {
773 r.rationalErrorMessage();
774 return false;
775 };
776 inline friend bool operator>=(const Rational& r, const float& s)
777 {
778 r.rationalErrorMessage();
779 return false;
780 };
781
782 inline friend bool operator!=(const float& r, const Rational& s)
783 {
784 s.rationalErrorMessage();
785 return false;
786 };
787 inline friend bool operator==(const float& r, const Rational& s)
788 {
789 s.rationalErrorMessage();
790 return false;
791 };
792 inline friend bool operator<(const float& r, const Rational& s)
793 {
794 s.rationalErrorMessage();
795 return false;
796 };
797 inline friend bool operator<=(const float& r, const Rational& s)
798 {
799 s.rationalErrorMessage();
800 return false;
801 };
802 inline friend bool operator>(const float& r, const Rational& s)
803 {
804 s.rationalErrorMessage();
805 return false;
806 };
807 inline friend bool operator>=(const float& r, const Rational& s)
808 {
809 s.rationalErrorMessage();
810 return false;
811 };
812
813 inline friend Rational operator+(const double& d, const Rational& r)
814 {
815 r.rationalErrorMessage();
816 return r;
817 };
818 inline friend Rational operator-(const double& d, const Rational& r)
819 {
820 r.rationalErrorMessage();
821 return r;
822 };
823 inline friend Rational operator*(const double& d, const Rational& r)
824 {
825 r.rationalErrorMessage();
826 return r;
827 };
828 inline friend Rational operator/(const double& d, const Rational& r)
829 {
830 r.rationalErrorMessage();
831 return r;
832 };
833
834 inline friend bool operator!=(const Rational& r, const int& s)
835 {
836 r.rationalErrorMessage();
837 return false;
838 };
839 inline friend bool operator==(const Rational& r, const int& s)
840 {
841 r.rationalErrorMessage();
842 return false;
843 };
844 inline friend bool operator<(const Rational& r, const int& s)
845 {
846 r.rationalErrorMessage();
847 return false;
848 };
849 inline friend bool operator<=(const Rational& r, const int& s)
850 {
851 r.rationalErrorMessage();
852 return false;
853 };
854 inline friend bool operator>(const Rational& r, const int& s)
855 {
856 r.rationalErrorMessage();
857 return false;
858 };
859 inline friend bool operator>=(const Rational& r, const int& s)
860 {
861 r.rationalErrorMessage();
862 return false;
863 };
864
865 inline friend bool operator!=(const int& r, const Rational& s)
866 {
867 s.rationalErrorMessage();
868 return false;
869 };
870 inline friend bool operator==(const int& r, const Rational& s)
871 {
872 s.rationalErrorMessage();
873 return false;
874 };
875 inline friend bool operator<(const int& r, const Rational& s)
876 {
877 s.rationalErrorMessage();
878 return false;
879 };
880 inline friend bool operator<=(const int& r, const Rational& s)
881 {
882 s.rationalErrorMessage();
883 return false;
884 };
885 inline friend bool operator>(const int& r, const Rational& s)
886 {
887 s.rationalErrorMessage();
888 return false;
889 };
890 inline friend bool operator>=(const int& r, const Rational& s)
891 {
892 s.rationalErrorMessage();
893 return false;
894 };
895
896 inline friend Rational operator+(const int& d, const Rational& r)
897 {
898 r.rationalErrorMessage();
899 return r;
900 };
901 inline friend Rational operator-(const int& d, const Rational& r)
902 {
903 r.rationalErrorMessage();
904 return r;
905 };
906 inline friend Rational operator*(const int& d, const Rational& r)
907 {
908 r.rationalErrorMessage();
909 return r;
910 };
911 inline friend Rational operator/(const int& d, const Rational& r)
912 {
913 r.rationalErrorMessage();
914 return r;
915 };
916
917 inline friend Rational spxAbs(const Rational& r)
918 {
919 r.rationalErrorMessage();
920 return r;
921 };
922 inline friend int sign(const Rational& r)
923 {
924 r.rationalErrorMessage();
925 return 0;
926 };
927 inline friend Rational operator-(const Rational& q)
928 {
929 q.rationalErrorMessage();
930 return q;
931 };///@name Construction and destruction
932 ///@{
933 };
934
935 inline Integer numerator(const Rational& r)
936 {
937 r.rationalErrorMessage();
938 return 0;
939 }
940 inline Integer denominator(const Rational& r)
941 {
942 r.rationalErrorMessage();
943 return 0;
944 }
945 inline Rational ratFromString(const char* desc)
946 {
947 return Rational();
948 }
949 inline int orderOfMagnitude(Rational& r)
950 {
951 r.rationalErrorMessage();
952 return 0;
953 }
954 inline void SpxLcm(Integer& result, Integer a, Integer b) {}
955 inline void SpxGcd(Integer& result, Integer a, Integer b) {}
956 inline void divide_qr(Integer& result, Integer& result2, Integer a, Integer b) {}
957 inline void invert(Rational& r)
958 {
959 r.rationalErrorMessage();
960 }
961 inline void powRound(Rational& r)
962 {
963 r.rationalErrorMessage();
964 }
965 #endif
966
967 namespace soplex
968 {
969
970 /// Size in specified base (bit size for base 2)
971 inline int sizeInBase(const Rational R, const int base)
972 {
973 #ifndef SOPLEX_WITH_BOOST
974 SPX_MSG_ERROR(std::cerr << "ERROR: rational solve without Boost not defined!" << std::endl;)
975 return 0;
976 #else
977
978 if(R == Rational(0))
979 return 3;
980
981 Integer num = numerator(R);
982 Integer den = denominator(R);
983 size_t numsize, densize;
984
985 #ifdef SOPLEX_WITH_GMP
986 densize = mpz_sizeinbase(den.backend().data(), base);
987 numsize = mpz_sizeinbase(num.backend().data(), base);
988 #else
989
990 if(base != 2)
991 {
992 densize = (size_t)(log2(den.convert_to<double>()) / log2(double(base))) + 1;
993 numsize = (size_t)(log2(num.convert_to<double>()) / log2(double(base))) + 1;
994 }
995 else
996 {
997 densize = msb(den) + 1;
998 numsize = msb(num) + 1;
999 }
1000
1001 #endif
1002
1003 return (int)(densize + numsize);
1004 #endif
1005 }
1006 /// Total size of rational vector.
1007 inline int totalSizeRational(const Rational* vector, const int length, const int base)
1008 {
1009 assert(vector != 0);
1010 assert(length >= 0);
1011 assert(base >= 0);
1012
1013 int size = 0;
1014
1015 for(int i = 0; i < length; i++)
1016 size += sizeInBase(vector[i], base);
1017
1018 return size;
1019 }
1020
1021 /// Size of least common multiple of denominators in rational vector.
1022 inline int dlcmSizeRational(const Rational* vector, const int length, const int base)
1023 {
1024 assert(vector != 0);
1025 assert(length >= 0);
1026
1027 #ifndef SOPLEX_WITH_BOOST
1028 SPX_MSG_ERROR(std::cerr << "ERROR: rational solve without Boost not defined!" << std::endl;)
1029 return 0;
1030 #else
1031
1032 Integer lcm = 1;
1033
1034 for(int i = 0; i < length; i++)
1035 SpxLcm(lcm, lcm, denominator(vector[i]));
1036
1037 int size = sizeInBase(Rational(lcm), base) + 1;
1038
1039 return size;
1040 #endif
1041 }
1042
1043 /// Size of largest denominator in rational vector.
1044 inline int dmaxSizeRational(const Rational* vector, const int length, const int base)
1045 {
1046 assert(vector != 0);
1047 assert(length >= 0);
1048 #ifndef SOPLEX_WITH_BOOST
1049 SPX_MSG_ERROR(std::cerr << "ERROR: rational solve without Boost not defined!" << std::endl;)
1050 return 0;
1051 #else
1052
1053 size_t dmax = 0;
1054
1055 for(int i = 0; i < length; i++)
1056 {
1057 size_t dsize = sizeInBase(Rational(denominator(vector[i])), base) + 1;
1058
1059 if(dsize > dmax)
1060 dmax = dsize;
1061 }
1062
1063 return (int)dmax;
1064 #endif
1065 }
1066
1067 } // namespace soplex
1068 #endif
1069 //}
1070