plll  1.0
arithmetic-gmp.hpp
Go to the documentation of this file.
1 /*
2  Copyright (c) 2011-2014 University of Zurich
3 
4  Permission is hereby granted, free of charge, to any person obtaining a copy
5  of this software and associated documentation files (the "Software"), to deal
6  in the Software without restriction, including without limitation the rights
7  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8  copies of the Software, and to permit persons to whom the Software is
9  furnished to do so, subject to the following conditions:
10 
11  The above copyright notice and this permission notice shall be included in
12  all copies or substantial portions of the Software.
13 
14  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20  THE SOFTWARE.
21 */
22 
23 #ifndef PLLL_INCLUDE_GUARD__ARITHMETIC_GMP_HPP
24 #define PLLL_INCLUDE_GUARD__ARITHMETIC_GMP_HPP
25 
26 #include <plll/config.hpp>
27 
40 namespace plll
41 {
42  namespace arithmetic
43  {
44 #ifdef PLLL_INTERNAL__BIGINT__HELP_FINDING_PRECISION_BUGS
45  namespace internal
46  {
47  extern bool Real_precision_check_enabled;
48  }
49 
50  inline void Real_precision_check_disable() { arithmetic::internal::Real_precision_check_enabled = false; }
51  inline void Real_precision_check_enable() { arithmetic::internal::Real_precision_check_enabled = true; }
52 #else
53  inline void Real_precision_check_disable() { }
54  inline void Real_precision_check_enable() { }
55 #endif
56  }
57 }
58 
59 #include <stdint.h>
60 #define MPFR_USE_INTMAX_T 1
61 
62 #include <gmp.h>
63 #include <mpfr.h>
64 #include <cmath>
65 #include <math.h>
66 #include <limits>
67 #include <iosfwd>
68 #include <cassert>
69 #include <utility>
70 #include <algorithm>
71 #include <plll/helper.hpp>
72 
73 namespace plll
74 {
75  namespace arithmetic
76  {
77 #if (MPFR_VERSION <= 0x0204FF)
78  // Versions 2.4.x or before: define MPFR_RNDN and others
79  #define MPFR_RNDN GMP_RNDN
80  #define MPFR_RNDZ GMP_RNDZ
81  #define MPFR_RNDU GMP_RNDU
82  #define MPFR_RNDD GMP_RNDD
83  typedef mp_exp_t mpfr_exp_t;
84 #endif
85 #if (__GMP_MP_RELEASE < 50000)
86  // Before version 5.0.0: define mp_bitcnt_t
87  typedef unsigned long mp_bitcnt_t;
88 #endif
89 
90  class Integer;
91  class IntegerContext;
92  class Real;
93  class RealContext;
94 
101  void swap(plll::arithmetic::Integer &, plll::arithmetic::Integer &) PLLL_INTERNAL_NOTHROW_POSTFIX_INLINE;
102 
106  void swap(plll::arithmetic::Real &, plll::arithmetic::Real &) PLLL_INTERNAL_NOTHROW_POSTFIX_INLINE;
108 
123 
133  inline bool isZero(const Integer &) PLLL_INTERNAL_NOTHROW_POSTFIX_INLINE;
134 
141  inline bool isZero(const Real &) PLLL_INTERNAL_NOTHROW_POSTFIX_INLINE;
142 
149  inline bool isOne(const Integer &) PLLL_INTERNAL_NOTHROW_POSTFIX_INLINE;
150 
157  inline bool isPMOne(const Integer &) PLLL_INTERNAL_NOTHROW_POSTFIX_INLINE;
158 
165  inline bool isPMTwo(const Integer &) PLLL_INTERNAL_NOTHROW_POSTFIX_INLINE;
166 
173  inline bool isOne(const Real &) PLLL_INTERNAL_NOTHROW_POSTFIX_INLINE;
174 
181  inline bool isPositive(const Integer &) PLLL_INTERNAL_NOTHROW_POSTFIX_INLINE;
182 
189  inline bool isPositive(const Real &) PLLL_INTERNAL_NOTHROW_POSTFIX_INLINE;
190 
197  inline bool isNonNegative(const Integer &) PLLL_INTERNAL_NOTHROW_POSTFIX_INLINE;
198 
205  inline bool isNonNegative(const Real &) PLLL_INTERNAL_NOTHROW_POSTFIX_INLINE;
206 
213  inline bool isNegative(const Integer &) PLLL_INTERNAL_NOTHROW_POSTFIX_INLINE;
214 
221  inline bool isNegative(const Real &) PLLL_INTERNAL_NOTHROW_POSTFIX_INLINE;
222 
229  inline bool isNonPositive(const Integer &) PLLL_INTERNAL_NOTHROW_POSTFIX_INLINE;
230 
237  inline bool isNonPositive(const Real &) PLLL_INTERNAL_NOTHROW_POSTFIX_INLINE;
239 
254  inline void euclideanDivision(Integer & q, Integer & r, const Integer & a, const Integer & b);
255 
266  inline void euclideanDivisionPos(Integer & q, Integer & r, const Integer & a, const Integer & b);
267 
276  inline void GCD(Integer & r, const Integer & x, const Integer & y);
277 
291  inline void XGCD(Integer & r, Integer & a, Integer & b, const Integer & x, const Integer & y);
292 
301  inline void LCM(Integer & r, const Integer & x, const Integer & y);
303 
310  std::ostream & operator << (std::ostream &, const Integer &);
314  std::istream & operator >> (std::istream &, Integer &);
318  std::ostream & operator << (std::ostream &, const Real &);
322  std::istream & operator >> (std::istream &, Real &);
324 
331  inline void setNaN(Real &);
339  inline void setInfinity(Real & r, bool sign = true);
343  inline void setZero(Integer &);
351  inline void setZero(Real & r, bool sign = true);
355  inline void setOne(Integer &);
359  inline void setOne(Real &);
361 
373  inline int compare(const Integer & a, const Integer & b);
382  inline int compare(const Real & a, const Real & b);
391  inline int compareAbsValues(const Integer & a, const Integer & b);
400  inline int compareAbsValues(const Real & a, const Real & b);
402 
412  inline int sign(const Integer &) PLLL_INTERNAL_NOTHROW_POSTFIX_INLINE;
420  inline int sign(const Real &) PLLL_INTERNAL_NOTHROW_POSTFIX_INLINE;
422 
430  inline int bit(const Integer & x, long n) PLLL_INTERNAL_NOTHROW_POSTFIX_INLINE;
438  inline void setbit(Integer & x, long n, bool value = true);
440 
451  inline void increment(Integer & r, const Integer & a);
458  inline void decrement(Integer & r, const Integer & a);
466  inline void add(Integer & r, const Integer & a, const Integer & b);
474  inline void sub(Integer & r, const Integer & a, const Integer & b);
482  inline void mul(Integer & r, const Integer & a, const Integer & b);
489  inline void neg(Integer & r, const Integer & a);
497  inline void div(Integer & r, const Integer & a, const Integer & b);
505  inline void mod(Integer & r, const Integer & a, const Integer & b);
515  inline void divmod(Integer & q, Integer & r, const Integer & a, const Integer & b);
522  inline void abs(Integer & r, const Integer & a);
530  inline void addmul(Integer & r, const Integer & a, const Integer & b);
538  inline void submul(Integer & r, const Integer & a, const Integer & b);
546  inline void band(Integer & r, const Integer & a, const Integer & b);
554  inline void bor(Integer & r, const Integer & a, const Integer & b);
562  inline void bxor(Integer & r, const Integer & a, const Integer & b);
569  inline void bneg(Integer & r, const Integer & a);
577  inline void shl(Integer & r, const Integer & a, long b);
585  inline void shl(Integer & r, const Integer & a, const Integer & b);
593  inline void shr(Integer & r, const Integer & a, long b);
601  inline void shr(Integer & r, const Integer & a, const Integer & b);
608  inline void square(Integer & r, const Integer & a);
609 
617  inline void add(Real & r, const Real & a, const Real & b);
625  inline void sub(Real & r, const Real & a, const Real & b);
633  inline void mul(Real & r, const Real & a, const Real & b);
641  inline void div(Real & r, const Real & a, const Real & b);
649  inline void mod(Real & r, const Real & a, const Real & b);
659  inline void divmod(Real & q, Real & r, const Real & a, const Real & b);
667  inline void shl(Real & r, const Real & a, const Real & b);
677  inline void shr(Real & r, const Real & a, const Real & b);
687  inline void shl(Real & r, const Real & a, long b);
695  inline void shr(Real & r, const Real & a, long b);
702  inline void increment(Real & r, const Real & a);
709  inline void decrement(Real & r, const Real & a);
716  inline void neg(Real & r, const Real & a);
723  inline void abs(Real & r, const Real & a);
731  inline void addmul(Real & r, const Real & a, const Real & b);
739  inline void submul(Real & r, const Real & a, const Real & b);
746  inline void square(Real & r, const Real & a);
748 
756  inline void makeAbs(Integer & a) PLLL_INTERNAL_NOTHROW_POSTFIX_INLINE;
762  inline void makeAbs(Real & a) PLLL_INTERNAL_NOTHROW_POSTFIX_INLINE;
764 
775  inline void power(Integer & r, const Integer & a, long b);
783  inline void power(Integer & r, const Integer & a, const Integer & b);
785 
795  inline void sqrtCeil(Integer & r, const Integer & a);
802  inline void sqrtFloor(Integer & r, const Integer & a);
803 
810  long approxLog2(const Integer & x) PLLL_INTERNAL_NOTHROW_POSTFIX_INLINE;
818  long ceilOfLog2(const Integer & x) PLLL_INTERNAL_NOTHROW_POSTFIX_INLINE;
826  long floorOfLog2(const Integer & x) PLLL_INTERNAL_NOTHROW_POSTFIX_INLINE;
834  inline long bitLength(const Integer & x) PLLL_INTERNAL_NOTHROW_POSTFIX_INLINE;
835 
844  void floorDiv(Integer & r, const Integer & a, const Integer & b);
853  void ceilDiv(Integer & r, const Integer & a, const Integer & b);
863  void roundDiv(Integer & r, const Integer & a, const Integer & b);
865 
876  inline void sin(Real & res, const Real & a);
884  inline void cos(Real & res, const Real & a);
892  inline void tan(Real & res, const Real & a);
900  inline void asin(Real & res, const Real & a);
908  inline void acos(Real & res, const Real & a);
916  inline void atan(Real & res, const Real & a);
927  inline void atan2(Real & res, const Real & y, const Real & x);
929 
940  inline void exp(Real & res, const Real & a);
947  inline void log(Real & res, const Real & a);
954  inline void log2(Real & res, const Real & a);
961  inline void log10(Real & res, const Real & a);
968  inline void sqrt(Real & res, const Real & a);
970 
981  inline void gamma(Real & res, const Real & a);
990  inline void lgamma(Real & res, const Real & a);
1001  inline void lgamma(Real & res, int & sign, const Real & a);
1010 
1015  inline void power(Real & res, const Real & a, long b);
1023  inline void power(Real & res, const Real & a, const Integer & b);
1032  inline void power(Real & res, const Real & a, const Real & b);
1034 
1041  {
1042  friend class arithmetic::Integer;
1043 
1044  public:
1053 
1057  enum { is_cputype = false, is_realtype = false, is_inttype = true, is_exact = true,
1058  is_modulo = false, has_infinity = false, has_uniform_rng = true };
1059 
1065  class UniformRNG;
1066  };
1067 
1071  class Integer
1072  {
1073  friend class Real;
1074  friend class RandomNumberGenerator;
1075 
1076 #ifndef PLLL_INTERNAL_NO_TEMPLATE_FRIENDS
1077  template<class X, class Y>
1078  friend class implementation::conversion_impl;
1079 
1080  friend class implementation::nativeconversion_impl<Integer>;
1081  friend class implementation::from_string_conversion<IntegerContext>;
1082  friend class implementation::to_string_conversion<Integer>;
1083 
1084  private:
1085 #else
1086  public:
1087 #endif
1088  mpz_t d_value;
1089 
1090  static void mpz_init_set_ld(mpz_t &, long double);
1091  static void mpz_set_ld(mpz_t &, long double);
1092  static long double mpz_get_ld(const mpz_t &);
1093  static void mpz_set_ll(mpz_t &, long long);
1094  static long long mpz_get_ll(const mpz_t &);
1095 
1096  public:
1100  typedef IntegerContext Context;
1101 
1105  inline Integer()
1106  {
1107  mpz_init(d_value);
1108  }
1109 
1115  inline explicit Integer(const IntegerContext & c)
1116  {
1117  mpz_init(d_value);
1118  }
1119 
1125  inline Integer(const Integer & i)
1126  {
1127  mpz_init_set(d_value, i.d_value);
1128  }
1129 
1136  inline Integer(const Integer & i, const IntegerContext & ic)
1137  {
1138  mpz_init_set(d_value, i.d_value);
1139  }
1140 
1146  inline explicit Integer(signed int i)
1147  {
1148  mpz_init_set_si(d_value, i);
1149  }
1150 
1156  inline explicit Integer(unsigned int i)
1157  {
1158  mpz_init_set_ui(d_value, i);
1159  }
1160 
1166  inline explicit Integer(signed long i)
1167  {
1168  mpz_init_set_si(d_value, i);
1169  }
1170 
1176  inline explicit Integer(unsigned long i)
1177  {
1178  mpz_init_set_ui(d_value, i);
1179  }
1180 
1186  inline explicit Integer(long long i)
1187  {
1188  mpz_init(d_value);
1189  mpz_set_ll(d_value, i);
1190  }
1191 
1198  inline explicit Integer(double d)
1199  {
1200  mpz_init_set_d(d_value, d);
1201  }
1202 
1209  inline explicit Integer(long double d)
1210  {
1211  mpz_init_set_ld(d_value, d);
1212  }
1213 
1219  template<class A, template<typename, typename> class O>
1221  {
1222  mpz_init(d_value);
1223  E.assignTo(*this);
1224  }
1225 
1232  template<class A, template<typename, typename> class O>
1233  inline Integer(const expressions::Expression<IntegerContext, A, O> & E, const IntegerContext & ic)
1234  {
1235  mpz_init(d_value);
1236  E.assignTo(*this);
1237  }
1238 
1242  inline ~Integer() PLLL_INTERNAL_NOTHROW_POSTFIX_INLINE
1243  {
1244 #if __cplusplus >= 201103L
1245  if (d_value[0]._mp_d != NULL)
1246 #endif
1247  mpz_clear(d_value);
1248  }
1249 
1250 #if __cplusplus >= 201103L
1251 
1256  inline Integer(Integer && i) PLLL_INTERNAL_NOTHROW_POSTFIX_INLINE
1257  : d_value{i.d_value[0]}
1258  {
1259  i.d_value[0]._mp_d = NULL;
1260  }
1261 
1267  inline Integer & operator = (Integer && i) PLLL_INTERNAL_NOTHROW_POSTFIX_INLINE
1268  {
1269  mpz_clear(d_value);
1270  d_value[0] = i.d_value[0];
1271  i.d_value[0]._mp_d = NULL;
1272  return *this;
1273  }
1274 #endif
1275 
1281  explicit Integer(const Real & r);
1282 
1288  static inline void setContext(const IntegerContext & c)
1289  {
1290  }
1291 
1295  inline Integer & operator = (const Integer & i)
1296  {
1297  mpz_set(d_value, i.d_value);
1298  return *this;
1299  }
1300 
1301  // Assign generic expression
1302  template<class A, template<typename, typename> class O>
1304  {
1305  E.assignTo(*this);
1306  return *this;
1307  }
1308 
1309  inline friend void increment(Integer & r, const Integer & a) // r = a + 1
1310  {
1311  mpz_add_ui(r.d_value, a.d_value, 1);
1312  }
1313 
1314  inline friend void decrement(Integer & r, const Integer & a) // r = a - 1
1315  {
1316  mpz_sub_ui(r.d_value, a.d_value, 1);
1317  }
1318 
1319  inline friend void add(Integer & r, const Integer & a, const Integer & b)
1320  {
1321  mpz_add(r.d_value, a.d_value, b.d_value);
1322  }
1323 
1324  inline friend void add_ui(Integer & r, const Integer & a, unsigned long b) // r = a + b
1325  // Internal for expression templates
1326  {
1327  mpz_add_ui(r.d_value, a.d_value, b);
1328  }
1329 
1330  inline friend void add_si(Integer & r, const Integer & a, signed long b) // r = a + b
1331  // Internal for expression templates
1332  {
1333  if (b < 0)
1334  mpz_sub_ui(r.d_value, a.d_value, -b);
1335  else
1336  mpz_add_ui(r.d_value, a.d_value, b);
1337  }
1338 
1339  inline friend void sub(Integer & r, const Integer & a, const Integer & b)
1340  {
1341  mpz_sub(r.d_value, a.d_value, b.d_value);
1342  }
1343 
1344  inline friend void sub_ui(Integer & r, const Integer & a, unsigned long b) // r = a - b
1345  // Internal for expression templates
1346  {
1347  mpz_sub_ui(r.d_value, a.d_value, b);
1348  }
1349 
1350  inline friend void sub_si(Integer & r, const Integer & a, signed long b) // r = a - b
1351  // Internal for expression templates
1352  {
1353  if (b < 0)
1354  mpz_add_ui(r.d_value, a.d_value, -b);
1355  else
1356  mpz_sub_ui(r.d_value, a.d_value, b);
1357  }
1358 
1359  inline friend void ui_sub(Integer & r, unsigned long a, const Integer & b) // r = a - b
1360  // Internal for expression templates
1361  {
1362  mpz_ui_sub(r.d_value, a, b.d_value);
1363  }
1364 
1365  inline friend void si_sub(Integer & r, signed long a, const Integer & b) // r = a - b
1366  // Internal for expression templates
1367  {
1368  if (a < 0)
1369  {
1370  mpz_add_ui(r.d_value, b.d_value, -a);
1371  mpz_neg(r.d_value, r.d_value);
1372  }
1373  else
1374  mpz_ui_sub(r.d_value, a, b.d_value);
1375  }
1376 
1377  inline friend void mul(Integer & r, const Integer & a, const Integer & b)
1378  {
1379  mpz_mul(r.d_value, a.d_value, b.d_value);
1380  }
1381 
1382  inline friend void mul_ui(Integer & r, const Integer & a, unsigned long b) // r = a * b
1383  // Internal for expression templates
1384  {
1385  mpz_mul_ui(r.d_value, a.d_value, b);
1386  }
1387 
1388  inline friend void mul_si(Integer & r, const Integer & a, signed long b) // r = a * b
1389  // Internal for expression templates
1390  {
1391  mpz_mul_si(r.d_value, a.d_value, b);
1392  }
1393 
1394  inline friend void neg(Integer & r, const Integer & a)
1395  {
1396  mpz_neg(r.d_value, a.d_value);
1397  }
1398 
1399  inline friend void div(Integer & r, const Integer & a, const Integer & b)
1400  {
1401  mpz_tdiv_q(r.d_value, a.d_value, b.d_value);
1402  }
1403 
1404  inline friend void div_ui(Integer & r, const Integer & a, unsigned long b) // r = a / b
1405  // Internal for expression templates
1406  {
1407  mpz_tdiv_q_ui(r.d_value, a.d_value, b);
1408  }
1409 
1410  inline friend void div_si(Integer & r, const Integer & a, signed long b) // r = a / b
1411  // Internal for expression templates
1412  {
1413  if (b < 0)
1414  {
1415  mpz_tdiv_q_ui(r.d_value, a.d_value, -b);
1416  mpz_neg(r.d_value, r.d_value);
1417  }
1418  else
1419  mpz_tdiv_q_ui(r.d_value, a.d_value, b);
1420  }
1421 
1422  inline friend void mod(Integer & r, const Integer & a, const Integer & b)
1423  {
1424  mpz_tdiv_r(r.d_value, a.d_value, b.d_value);
1425  }
1426 
1427  inline friend void mod_ui(Integer & r, const Integer & a, unsigned long b) // r = a % b
1428  // Internal for expression templates
1429  {
1430  mpz_tdiv_r_ui(r.d_value, a.d_value, b);
1431  }
1432 
1433  inline friend void mod_si(Integer & r, const Integer & a, signed long b) // r = a % b
1434  // Internal for expression templates
1435  {
1436  mpz_tdiv_r_ui(r.d_value, a.d_value, (b < 0) ? -b : b);
1437  }
1438 
1439  inline friend void divmod(Integer & q, Integer & r, const Integer & a, const Integer & b)
1440  {
1441  mpz_tdiv_qr(q.d_value, r.d_value, a.d_value, b.d_value);
1442  }
1443 
1444  inline friend void divmod_ui(Integer & q, Integer & r, const Integer & a, unsigned long b)
1445  // Internal for expression templates
1446  {
1447  mpz_tdiv_qr_ui(q.d_value, r.d_value, a.d_value, b);
1448  }
1449 
1450  inline friend void divmod_si(Integer & q, Integer & r, const Integer & a, signed long b)
1451  // Internal for expression templates
1452  {
1453  mpz_tdiv_qr_ui(q.d_value, r.d_value, a.d_value, (b < 0) ? -b : b);
1454  if (b < 0)
1455  mpz_neg(q.d_value, q.d_value);
1456  }
1457 
1458  inline friend void abs(Integer & r, const Integer & a)
1459  {
1460  mpz_abs(r.d_value, a.d_value);
1461  }
1462 
1463  inline friend void addmul(Integer & r, const Integer & a, const Integer & b) // r += a * b
1464  {
1465  mpz_addmul(r.d_value, a.d_value, b.d_value);
1466  }
1467 
1468  inline friend void addmul_ui(Integer & r, const Integer & a, unsigned long b) // r += a * b
1469  // Internal for expression templates
1470  {
1471  mpz_addmul_ui(r.d_value, a.d_value, b);
1472  }
1473 
1474  inline friend void addmul_si(Integer & r, const Integer & a, signed long b) // r += a * b
1475  // Internal for expression templates
1476  {
1477  if (b < 0)
1478  mpz_submul_ui(r.d_value, a.d_value, -b);
1479  else
1480  mpz_addmul_ui(r.d_value, a.d_value, b);
1481  }
1482 
1483  inline friend void submul(Integer & r, const Integer & a, const Integer & b) // r -= a * b
1484  {
1485  mpz_submul(r.d_value, a.d_value, b.d_value);
1486  }
1487 
1488  inline friend void submul_ui(Integer & r, const Integer & a, unsigned long b) // r -= a * b
1489  // Internal for expression templates
1490  {
1491  mpz_submul_ui(r.d_value, a.d_value, b);
1492  }
1493 
1494  inline friend void submul_si(Integer & r, const Integer & a, signed long b) // r -= a * b
1495  // Internal for expression templates
1496  {
1497  if (b < 0)
1498  mpz_addmul_ui(r.d_value, a.d_value, -b);
1499  else
1500  mpz_submul_ui(r.d_value, a.d_value, b);
1501  }
1502 
1503  inline friend void power(Integer & r, const Integer & a, long b)
1504  {
1505  if (b < 0)
1506  mpz_set_ui(r.d_value, 0);
1507  else
1508  mpz_pow_ui(r.d_value, a.d_value, b);
1509  }
1510 
1511  inline friend void power(Integer & r, const Integer & a, const Integer & b)
1512  {
1513  if (sign(b) < 0)
1514  mpz_set_ui(r.d_value, 0);
1515  else
1516  mpz_pow_ui(r.d_value, a.d_value, mpz_get_ui(b.d_value));
1517  }
1518 
1519  inline friend void floorDiv(Integer & r, const Integer & a, const Integer & b) // Computes r = floor(a/b), where b \neq 0.
1520  {
1521  mpz_fdiv_q(r.d_value, a.d_value, b.d_value);
1522  }
1523 
1524  inline friend void ceilDiv(Integer & r, const Integer & a, const Integer & b) // Computes r = ceil(a/b), where b \neq 0.
1525  {
1526  mpz_cdiv_q(r.d_value, a.d_value, b.d_value);
1527  }
1528 
1529  inline friend void roundDiv(Integer & r, const Integer & a, const Integer & b) // Computes r = round(a/b), where b \neq 0.
1530  {
1531  mpz_t rem;
1532  mpz_init(rem);
1533  mpz_fdiv_qr(r.d_value, rem, a.d_value, b.d_value);
1534  mpz_mul_2exp(rem, rem, 1);
1535  if (mpz_cmp(rem, b.d_value) > 0)
1536  mpz_add_ui(r.d_value, r.d_value, 1);
1537  mpz_clear(rem);
1538  }
1539 
1540  inline friend void sqrtCeil(Integer & r, const Integer & a)
1541  {
1542  mpz_t rr;
1543  mpz_init(rr);
1544  mpz_sqrtrem(r.d_value, rr, a.d_value);
1545  if (mpz_sgn(rr) != 0)
1546  increment(r, r);
1547  mpz_clear(rr);
1548  }
1549 
1550  inline friend void sqrtFloor(Integer & r, const Integer & a)
1551  {
1552  mpz_sqrt(r.d_value, a.d_value);
1553  }
1554 
1555  inline friend void band(Integer & r, const Integer & a, const Integer & b)
1556  {
1557  mpz_and(r.d_value, a.d_value, b.d_value);
1558  }
1559 
1560  inline friend void bor(Integer & r, const Integer & a, const Integer & b)
1561  {
1562  mpz_ior(r.d_value, a.d_value, b.d_value);
1563  }
1564 
1565  inline friend void bxor(Integer & r, const Integer & a, const Integer & b)
1566  {
1567  mpz_xor(r.d_value, a.d_value, b.d_value);
1568  }
1569 
1570  inline friend void bneg(Integer & r, const Integer & a)
1571  {
1572  mpz_com(r.d_value, a.d_value);
1573  }
1574 
1575  inline friend void shl(Integer & r, const Integer & a, long b)
1576  {
1577  if (b < 0)
1578  mpz_tdiv_q_2exp(r.d_value, a.d_value, -b);
1579  else
1580  mpz_mul_2exp(r.d_value, a.d_value, b);
1581  }
1582 
1583  inline friend void shl(Integer & r, const Integer & a, const Integer & b)
1584  {
1585  mpz_mul_2exp(r.d_value, a.d_value, mpz_get_ui(b.d_value));
1586  }
1587 
1588  inline friend void shr(Integer & r, const Integer & a, long b)
1589  {
1590  if (b < 0)
1591  mpz_mul_2exp(r.d_value, a.d_value, -b);
1592  else
1593  mpz_tdiv_q_2exp(r.d_value, a.d_value, b);
1594  }
1595 
1596  inline friend void shr(Integer & r, const Integer & a, const Integer & b)
1597  {
1598  mpz_tdiv_q_2exp(r.d_value, a.d_value, mpz_get_ui(b.d_value));
1599  }
1600 
1601  inline friend bool isZero(const Integer & i) PLLL_INTERNAL_NOTHROW_POSTFIX_INLINE
1602  {
1603  return mpz_sgn(i.d_value) == 0;
1604  }
1605 
1606  inline friend bool isOne(const Integer & i) PLLL_INTERNAL_NOTHROW_POSTFIX_INLINE
1607  {
1608  return mpz_cmp_ui(i.d_value, 1) == 0;
1609  }
1610 
1611  inline friend bool isPMOne(const Integer & i) PLLL_INTERNAL_NOTHROW_POSTFIX_INLINE
1612  {
1613  return mpz_cmpabs_ui(i.d_value, 1) == 0;
1614  }
1615 
1616  inline friend bool isPMTwo(const Integer & i) PLLL_INTERNAL_NOTHROW_POSTFIX_INLINE
1617  {
1618  return mpz_cmpabs_ui(i.d_value, 2) == 0;
1619  }
1620 
1621  inline friend bool isPositive(const Integer & i) PLLL_INTERNAL_NOTHROW_POSTFIX_INLINE
1622  {
1623  return mpz_sgn(i.d_value) > 0;
1624  }
1625 
1626  inline friend bool isNonNegative(const Integer & i) PLLL_INTERNAL_NOTHROW_POSTFIX_INLINE
1627  {
1628  return mpz_sgn(i.d_value) >= 0;
1629  }
1630 
1631  inline friend bool isNegative(const Integer & i) PLLL_INTERNAL_NOTHROW_POSTFIX_INLINE
1632  {
1633  return mpz_sgn(i.d_value) < 0;
1634  }
1635 
1636  inline friend bool isNonPositive(const Integer & i) PLLL_INTERNAL_NOTHROW_POSTFIX_INLINE
1637  {
1638  return mpz_sgn(i.d_value) <= 0;
1639  }
1640 
1641  inline friend void makeAbs(Integer & a) PLLL_INTERNAL_NOTHROW_POSTFIX_INLINE
1642  {
1643  abs(a, a);
1644  }
1645 
1646  inline friend void euclideanDivision(Integer & q, Integer & r, const Integer & a, const Integer & b)
1647  // Given b \neq 0, computes q, r such that a = q b + r, 0 <= |r| < |b| and b*r >= 0.
1648  {
1649  mpz_tdiv_qr(q.d_value, r.d_value, a.d_value, b.d_value);
1650  }
1651 
1652  inline friend void euclideanDivisionPos(Integer & q, Integer & r, const Integer & a, const Integer & b)
1653  // Given b \neq 0, computes q, r such that a = q b + r, 0 <= r < |b|
1654  {
1655  mpz_fdiv_qr(q.d_value, r.d_value, a.d_value, b.d_value);
1656  }
1657 
1658  inline friend void GCD(Integer & r, const Integer & x, const Integer & y)
1659  // Computes the gcd of x and y.
1660  {
1661  mpz_gcd(r.d_value, x.d_value, y.d_value);
1662  }
1663 
1664  inline friend void GCD_ui(Integer & r, const Integer & x, unsigned long y)
1665  // Internal for expression templates
1666  {
1667  mpz_gcd_ui(r.d_value, x.d_value, y);
1668  }
1669 
1670  inline friend void GCD_si(Integer & r, const Integer & x, signed long y)
1671  // Internal for expression templates
1672  {
1673  mpz_gcd_ui(r.d_value, x.d_value, y < 0 ? -y : y);
1674  }
1675 
1676  inline friend void XGCD(Integer & r, Integer & a, Integer & b, const Integer & x, const Integer & y)
1677  // Computes the gcd of x and y. Also computes a, b such that gcd = a*x + b*y.
1678  {
1679  mpz_gcdext(r.d_value, a.d_value, b.d_value, x.d_value, y.d_value);
1680  }
1681 
1682  inline friend void LCM(Integer & r, const Integer & x, const Integer & y)
1683  // Computes the lcm of x and y.
1684  {
1685  mpz_lcm(r.d_value, x.d_value, y.d_value);
1686  }
1687 
1688  inline friend void LCM_ui(Integer & r, const Integer & x, unsigned long y)
1689  // Internal for expression templates
1690  {
1691  mpz_lcm_ui(r.d_value, x.d_value, y);
1692  }
1693 
1694  inline friend void LCM_si(Integer & r, const Integer & x, signed long y)
1695  // Internal for expression templates
1696  {
1697  mpz_lcm_ui(r.d_value, x.d_value, y < 0 ? -y : y);
1698  }
1699 
1700  friend std::ostream & operator << (std::ostream & s, const Integer & i);
1701  // Output to stream
1702 
1703  friend std::istream & operator >> (std::istream & s, Integer & i);
1704  // Input from stream
1705 
1706  inline friend void setZero(Integer & i)
1707  // Set to zero
1708  {
1709  mpz_set_ui(i.d_value, 0);
1710  }
1711 
1712  inline friend void setOne(Integer & i)
1713  // Set to one
1714  {
1715  mpz_set_ui(i.d_value, 1);
1716  }
1717 
1718  inline friend int compare(const Integer & a, const Integer & b)
1719  // Tests whether the first integer is < (-1), = (0) or > (1) than the second.
1720  {
1721  return mpz_cmp(a.d_value, b.d_value);
1722  }
1723 
1724  inline friend int compare_d(const Integer & a, double b)
1725  // Internal for expression templates
1726  {
1727  return mpz_cmp_d(a.d_value, b);
1728  }
1729 
1730  inline friend int compare_ui(const Integer & a, unsigned long b)
1731  // Internal for expression templates
1732  {
1733  return mpz_cmp_ui(a.d_value, b);
1734  }
1735 
1736  inline friend int compare_si(const Integer & a, signed long b)
1737  // Internal for expression templates
1738  {
1739  return mpz_cmp_si(a.d_value, b);
1740  }
1741 
1742  inline friend int compareAbsValues(const Integer & a, const Integer & b)
1743  // Tests whether the absolute value of the first integer is < (-1), = (0) or > (1) than the
1744  // absolute value of the second integer.
1745  {
1746  return mpz_cmpabs(a.d_value, b.d_value);
1747  }
1748 
1749  inline friend int compareAbsValues_d(const Integer & a, double b)
1750  // Internal for expression templates
1751  {
1752  return mpz_cmpabs_d(a.d_value, b);
1753  }
1754 
1755  inline friend int compareAbsValues_si(const Integer & a, signed long b)
1756  // Internal for expression templates
1757  {
1758  return mpz_cmpabs_ui(a.d_value, b < 0 ? -b : b);
1759  }
1760 
1761  inline friend int compareAbsValues_ui(const Integer & a, unsigned long b)
1762  // Internal for expression templates
1763  {
1764  return mpz_cmpabs_ui(a.d_value, b);
1765  }
1766 
1767  inline friend int sign(const Integer & i) PLLL_INTERNAL_NOTHROW_POSTFIX_INLINE
1768  // Returns the sign (i.e. -1, 0, 1).
1769  {
1770  return mpz_sgn(i.d_value);
1771  }
1772 
1773  inline friend int bit(const Integer & x, long n) PLLL_INTERNAL_NOTHROW_POSTFIX_INLINE
1774  // Returns the n-th bit of the given integer.
1775  {
1776  return mpz_tstbit(x.d_value, n);
1777  }
1778 
1779  inline friend void setbit(Integer & x, long n, bool value)
1780  // Sets the n-th bit of the given integer.
1781  {
1782  if (value)
1783  mpz_setbit(x.d_value, n);
1784  else
1785  mpz_clrbit(x.d_value, n);
1786  }
1787 
1788  inline friend void square(Integer & r, const Integer & a)
1789  {
1790  mpz_mul(r.d_value, a.d_value, a.d_value);
1791  }
1792 
1793  inline friend long approxLog2(const Integer & x) PLLL_INTERNAL_NOTHROW_POSTFIX_INLINE // Returns ~log_2(|x|).
1794  {
1795  return mpz_sizeinbase(x.d_value, 2);
1796  }
1797 
1798  inline friend long ceilOfLog2(const Integer & x) PLLL_INTERNAL_NOTHROW_POSTFIX_INLINE // Returns ceil(log_2(|x|)).
1799  {
1800  mp_bitcnt_t r = mpz_sizeinbase(x.d_value, 2);
1801  mp_bitcnt_t lsb = mpz_scan1(x.d_value, 0);
1802  return (lsb < r - 1) ? r : r - 1;
1803  }
1804 
1805  inline friend long floorOfLog2(const Integer & x) PLLL_INTERNAL_NOTHROW_POSTFIX_INLINE // Returns floor(log_2(|x|)).
1806  {
1807  return (long)mpz_sizeinbase(x.d_value, 2) - 1;
1808  }
1809 
1810  inline friend long bitLength(const Integer & x) PLLL_INTERNAL_NOTHROW_POSTFIX_INLINE // Returns n such that 2^{n-1} <= |x| < 2^n
1811  {
1812  return (long)mpz_sizeinbase(x.d_value, 2);
1813  }
1814 
1815  inline friend void arithmetic::swap(plll::arithmetic::Integer &, plll::arithmetic::Integer &) PLLL_INTERNAL_NOTHROW_POSTFIX_INLINE;
1816 
1817  inline friend void power(Real & res, const Real & a, const Integer & b);
1818 
1819  // These ones should only be used in very, very special and rare cases!
1820  inline const mpz_t & getInternal() const PLLL_INTERNAL_NOTHROW_POSTFIX_INLINE { return d_value; }
1821  inline mpz_t & getInternal() PLLL_INTERNAL_NOTHROW_POSTFIX_INLINE { return d_value; }
1822 
1823  inline friend bool operator == (const Integer & a, const Integer & b);
1824  inline friend bool operator != (const Integer & a, const Integer & b);
1825  inline friend bool operator <= (const Integer & a, const Integer & b);
1826  inline friend bool operator >= (const Integer & a, const Integer & b);
1827  inline friend bool operator < (const Integer & a, const Integer & b);
1828  inline friend bool operator > (const Integer & a, const Integer & b);
1829  };
1830 
1831  // Internal for expression templates
1832  inline void add_ui(Integer & r, const Integer & a, unsigned long b); // r = a + b
1833  inline void add_si(Integer & r, const Integer & a, signed long b); // r = a + b
1834  inline void sub_ui(Integer & r, const Integer & a, unsigned long b); // r = a - b
1835  inline void sub_si(Integer & r, const Integer & a, signed long b); // r = a - b
1836  inline void ui_sub(Integer & r, unsigned long a, const Integer & b); // r = a - b
1837  inline void si_sub(Integer & r, signed long a, const Integer & b); // r = a - b
1838  inline void mul_ui(Integer & r, const Integer & a, unsigned long b); // r = a * b
1839  inline void mul_si(Integer & r, const Integer & a, signed long b); // r = a * b
1840  inline void div_ui(Integer & r, const Integer & a, unsigned long b); // r = a / b
1841  inline void div_si(Integer & r, const Integer & a, signed long b); // r = a / b
1842  inline void mod_ui(Integer & r, const Integer & a, unsigned long b); // r = a % b
1843  inline void mod_si(Integer & r, const Integer & a, signed long b); // r = a % b
1844  inline void addmul_ui(Integer & r, const Integer & a, unsigned long b); // r += a * b
1845  inline void addmul_si(Integer & r, const Integer & a, signed long b); // r += a * b
1846  inline void submul_ui(Integer & r, const Integer & a, unsigned long b); // r -= a * b
1847  inline void submul_si(Integer & r, const Integer & a, signed long b); // r -= a * b
1848  inline void GCD_ui(Integer & r, const Integer & x, unsigned long y);
1849  inline void GCD_si(Integer & r, const Integer & x, signed long y);
1850  inline void LCM_ui(Integer & r, const Integer & x, unsigned long y);
1851  inline void LCM_si(Integer & r, const Integer & x, signed long y);
1852  inline int compare_d(const Integer & a, double b);
1853  inline int compare_ui(const Integer & a, unsigned long b);
1854  inline int compare_si(const Integer & a, signed long b);
1855  inline int compareAbsValues_d(const Integer & a, double b);
1856  inline int compareAbsValues_si(const Integer & a, signed long b);
1857  inline int compareAbsValues_ui(const Integer & a, unsigned long b);
1858  }
1859 }
1860 
1861 #include "arithmetic-gmp-iops.hpp"
1862 
1863 namespace plll
1864 {
1865  namespace arithmetic
1866  {
1873  {
1874  friend class arithmetic::Real;
1875  friend RealContext & getThreadRealContext();
1876 
1877  // stores information like precision (for Real)
1878 
1879  long d_prec;
1880  bool d_global;
1881 
1882  private:
1883  inline explicit RealContext(bool global)
1884  : d_prec(mpfr_get_default_prec()), d_global(true)
1885  {
1886  }
1887 
1888  public:
1897 
1901  enum { is_cputype = false, is_realtype = true, is_inttype = false, is_exact = false, is_variable_precision = true,
1902  has_squareroot = true, has_full_power = true, has_special_fns = true, has_huge_exponent = true,
1903  has_infinity = true, has_uniform_rng = true, has_constants = true, has_trigonometric = true };
1904 
1908  inline RealContext() PLLL_INTERNAL_NOTHROW_POSTFIX_INLINE
1909  : d_prec(mpfr_get_default_prec()), d_global(false)
1910  {
1911  }
1912 
1916  inline explicit RealContext(long prec) PLLL_INTERNAL_NOTHROW_POSTFIX_INLINE
1917  : d_prec(prec < MPFR_PREC_MIN ? MPFR_PREC_MIN : (prec > MPFR_PREC_MAX ? MPFR_PREC_MAX : prec)), d_global(false)
1918  {
1919  }
1920 
1929  inline void setRealPrecision(unsigned long prec) PLLL_INTERNAL_NOTHROW_POSTFIX_INLINE
1930  {
1931  if (prec < MPFR_PREC_MIN) prec = MPFR_PREC_MIN;
1932  if (prec > MPFR_PREC_MAX) prec = MPFR_PREC_MAX;
1933  if (d_global)
1934  mpfr_set_default_prec(prec);
1935  else
1936  d_prec = prec;
1937  }
1938 
1942  inline unsigned long getRealPrecision() const PLLL_INTERNAL_NOTHROW_POSTFIX_INLINE
1943  {
1944  return d_global ? mpfr_get_default_prec() : d_prec;
1945  }
1946 
1950  static inline unsigned long getMinRealPrecision() PLLL_INTERNAL_NOTHROW_POSTFIX_INLINE // returns minimal value for precision
1951  {
1952  return MPFR_PREC_MIN;
1953  }
1954 
1958  static inline unsigned long getMaxRealPrecision() PLLL_INTERNAL_NOTHROW_POSTFIX_INLINE // returns maximal value for precision
1959  {
1960  return MPFR_PREC_MAX;
1961  }
1962 
1968  inline Real getEpsilon() const;
1974  inline void getEpsilon(Real &) const;
1975 
1981  inline Real getPi() const;
1987  inline void getPi(Real &) const;
1988 
1995  inline Real getEuler() const;
2002  inline void getEuler(Real &) const;
2003 
2010  inline Real getLog2() const;
2017  inline void getLog2(Real &) const;
2018 
2024  class UniformRNG;
2025  };
2026 
2031  RealContext & getThreadRealContext(); // returns context for current thread
2032 
2036  class Real
2037  {
2038  friend class RandomNumberGenerator;
2039  friend class RealContext;
2040 
2041 #ifndef PLLL_INTERNAL_NO_TEMPLATE_FRIENDS
2042  template<class X, class Y>
2043  friend class implementation::conversion_impl;
2044 
2045  friend class implementation::nativeconversion_impl<Real>;
2046  friend class implementation::from_string_conversion<RealContext>;
2047  friend class implementation::to_string_conversion<Real>;
2048 
2049  private:
2050 #else
2051  public:
2052 #endif
2053  mpfr_t d_value;
2054 
2055  inline Real(bool, unsigned long p)
2056  {
2057  mpfr_init2(d_value, p);
2058  }
2059 
2060  static void mpfr_set_ll(mpfr_t &, long long, mpfr_rnd_t);
2061  static long long mpfr_get_ll(const mpfr_t &, mpfr_rnd_t);
2062  static long long mpfr_get_ll(const mpfr_t &, mpfr_rnd_t, bool & roundUp);
2063 
2064  public:
2065  // Internal helper for the expression template classes (we don't want to friend them
2066  // all explicitly!).
2068  {
2069  unsigned long precision;
2070 
2071  inline PrecisionInit(unsigned long prec) PLLL_INTERNAL_NOTHROW_POSTFIX_INLINE
2072  : precision(prec)
2073  {
2074  }
2075  };
2076 
2077  inline Real(PrecisionInit p)
2078  {
2079  mpfr_init2(d_value, p.precision);
2080  }
2081 
2082  public:
2086  typedef RealContext Context;
2087 
2093  inline Real()
2094  {
2095  mpfr_init(d_value);
2096  }
2097 
2101  inline ~Real() PLLL_INTERNAL_NOTHROW_POSTFIX_INLINE
2102  {
2103 #if __cplusplus >= 201103L
2104  if (d_value[0]._mpfr_d != NULL)
2105 #endif
2106  mpfr_clear(d_value);
2107  }
2108 
2109 #if __cplusplus >= 201103L
2110 
2115  inline Real(Real && r) PLLL_INTERNAL_NOTHROW_POSTFIX_INLINE
2116  : d_value{r.d_value[0]}
2117  {
2118  r.d_value[0]._mpfr_d = NULL;
2119  }
2120 
2126  inline Real & operator = (Real && r) PLLL_INTERNAL_NOTHROW_POSTFIX_INLINE
2127  {
2128  mpfr_clear(d_value);
2129  d_value[0] = r.d_value[0];
2130  r.d_value[0]._mpfr_d = NULL;
2131  return *this;
2132  }
2133 #endif
2134 
2140  inline explicit Real(const RealContext & rc)
2141  {
2142  mpfr_init2(d_value, rc.getRealPrecision());
2143  }
2144 
2152  inline Real(const Real & r, bool clone = true)
2153  {
2154  if (clone)
2155  {
2156  mpfr_init2(d_value, mpfr_get_prec(r.d_value));
2157  mpfr_set(d_value, r.d_value, MPFR_RNDN);
2158  }
2159  else
2160  mpfr_init_set(d_value, r.d_value, MPFR_RNDN);
2161  }
2162 
2170  inline explicit Real(const Real & r, const RealContext & rc)
2171  {
2172  mpfr_init2(d_value, rc.getRealPrecision());
2173  mpfr_set(d_value, r.d_value, MPFR_RNDN);
2174  }
2175 
2181  inline unsigned long precision() const PLLL_INTERNAL_NOTHROW_POSTFIX_INLINE
2182  {
2183  return mpfr_get_prec(d_value);
2184  }
2185 
2192  inline void setContext(const RealContext & rc)
2193  {
2194  if (rc.getRealPrecision() != precision())
2195  {
2196  mpfr_t tmp;
2197  mpfr_init2(tmp, rc.getRealPrecision());
2198  mpfr_set(tmp, d_value, MPFR_RNDN);
2199  mpfr_swap(tmp, d_value);
2200  mpfr_clear(tmp);
2201  }
2202  }
2203 
2209  inline explicit Real(long i)
2210  {
2211  mpfr_init_set_si(d_value, i, MPFR_RNDN);
2212  }
2213 
2221  inline explicit Real(long i, const RealContext & rc)
2222  {
2223  mpfr_init2(d_value, rc.getRealPrecision());
2224  mpfr_set_si(d_value, i, MPFR_RNDN);
2225  }
2226 
2232  inline explicit Real(unsigned long i)
2233  {
2234  mpfr_init_set_ui(d_value, i, MPFR_RNDN);
2235  }
2236 
2244  inline explicit Real(unsigned long i, const RealContext & rc)
2245  {
2246  mpfr_init2(d_value, rc.getRealPrecision());
2247  mpfr_set_ui(d_value, i, MPFR_RNDN);
2248  }
2249 
2255  inline explicit Real(long long i)
2256  {
2257  mpfr_init(d_value);
2258  mpfr_set_ll(d_value, i, MPFR_RNDN);
2259  }
2260 
2268  inline explicit Real(long long i, const RealContext & rc)
2269  {
2270  mpfr_init2(d_value, rc.getRealPrecision());
2271  mpfr_set_ll(d_value, i, MPFR_RNDN);
2272  }
2273 
2280  inline explicit Real(double d)
2281  {
2282  mpfr_init_set_d(d_value, d, MPFR_RNDN);
2283  }
2284 
2292  inline explicit Real(double d, const RealContext & rc)
2293  {
2294  mpfr_init2(d_value, rc.getRealPrecision());
2295  mpfr_set_d(d_value, d, MPFR_RNDN);
2296  }
2297 
2304  inline explicit Real(long double d)
2305  {
2306  mpfr_init_set_ld(d_value, d, MPFR_RNDN);
2307  }
2308 
2316  inline explicit Real(long double d, const RealContext & rc)
2317  {
2318  mpfr_init2(d_value, rc.getRealPrecision());
2319  mpfr_set_ld(d_value, d, MPFR_RNDN);
2320  }
2321 
2328  inline explicit Real(const Integer & i)
2329  {
2330  mpfr_init_set_z(d_value, i.d_value, MPFR_RNDN);
2331  }
2332 
2340  inline explicit Real(const Integer & i, const RealContext & rc)
2341  {
2342  mpfr_init2(d_value, rc.getRealPrecision());
2343  mpfr_set_z(d_value, i.d_value, MPFR_RNDN);
2344  }
2345 
2351  template<class A, template<typename, typename> class O>
2353  {
2354  mpfr_init2(d_value, E.precision());
2355  E.assignTo(*this);
2356  }
2357 
2365  template<class A, template<typename, typename> class O>
2366  inline Real(const expressions::Expression<RealContext, A, O> & E, const RealContext & rc)
2367  {
2368  mpfr_init2(d_value, rc.getRealPrecision());
2369  E.assignTo(*this);
2370  }
2371 
2378  inline Real & operator = (const Real & r)
2379  {
2380  #ifdef PLLL_INTERNAL__BIGINT__HELP_FINDING_PRECISION_BUGS
2381  if (arithmetic::internal::Real_precision_check_enabled)
2382  assert(mpfr_get_prec(d_value) == mpfr_get_prec(r.d_value));
2383  #endif
2384  mpfr_set(d_value, r.d_value, MPFR_RNDN);
2385  return *this;
2386  }
2387 
2394  template<class A, template<typename, typename> class O>
2396  {
2397  E.assignTo(*this);
2398  return *this;
2399  }
2400 
2401  inline friend bool operator == (const Real & a, const Real & b);
2402  inline friend bool operator != (const Real & a, const Real & b);
2403  inline friend bool operator <= (const Real & a, const Real & b);
2404  inline friend bool operator >= (const Real & a, const Real & b);
2405  inline friend bool operator < (const Real & a, const Real & b);
2406  inline friend bool operator > (const Real & a, const Real & b);
2407 
2408  inline friend bool isZero(const Real & r) PLLL_INTERNAL_NOTHROW_POSTFIX_INLINE
2409  // Tests whether the given value is = 0.
2410  {
2411  return mpfr_zero_p(r.d_value);
2412  }
2413 
2414  inline friend bool isOne(const Real & r) PLLL_INTERNAL_NOTHROW_POSTFIX_INLINE
2415  // Tests whether the given value is = 1.
2416  {
2417  return mpfr_cmp_ui(r.d_value, 1) == 0;
2418  }
2419 
2420  inline friend bool isPositive(const Real & r) PLLL_INTERNAL_NOTHROW_POSTFIX_INLINE
2421  // Tests whether the given value is > 0.
2422  {
2423  return mpfr_sgn(r.d_value) > 0;
2424  }
2425 
2426  inline friend bool isNonNegative(const Real & r) PLLL_INTERNAL_NOTHROW_POSTFIX_INLINE
2427  // Tests whether the given value is >= 0.
2428  {
2429  return mpfr_sgn(r.d_value) >= 0;
2430  }
2431 
2432  inline friend bool isNegative(const Real & r) PLLL_INTERNAL_NOTHROW_POSTFIX_INLINE
2433  // Tests whether the given value is < 0.
2434  {
2435  return mpfr_sgn(r.d_value) < 0;
2436  }
2437 
2438  inline friend bool isNonPositive(const Real & r) PLLL_INTERNAL_NOTHROW_POSTFIX_INLINE
2439  // Tests whether the given value is <= 0.
2440  {
2441  return mpfr_sgn(r.d_value) <= 0;
2442  }
2443 
2444  inline friend void add(Real & r, const Real & a, const Real & b)
2445  {
2446  #ifdef PLLL_INTERNAL__BIGINT__HELP_FINDING_PRECISION_BUGS
2447  if (arithmetic::internal::Real_precision_check_enabled)
2448  {
2449  assert(mpfr_get_prec(r.d_value) == mpfr_get_prec(a.d_value));
2450  assert(mpfr_get_prec(r.d_value) == mpfr_get_prec(b.d_value));
2451  }
2452  #endif
2453  mpfr_add(r.d_value, a.d_value, b.d_value, MPFR_RNDN);
2454  }
2455 
2456  inline friend void add_ui(Real & r, const Real & a, unsigned long b)
2457  // Internal for expression templates
2458  {
2459  #ifdef PLLL_INTERNAL__BIGINT__HELP_FINDING_PRECISION_BUGS
2460  if (arithmetic::internal::Real_precision_check_enabled)
2461  assert(mpfr_get_prec(r.d_value) == mpfr_get_prec(a.d_value));
2462  #endif
2463  mpfr_add_ui(r.d_value, a.d_value, b, MPFR_RNDN);
2464  }
2465 
2466  inline friend void add_si(Real & r, const Real & a, signed long b)
2467  // Internal for expression templates
2468  {
2469  #ifdef PLLL_INTERNAL__BIGINT__HELP_FINDING_PRECISION_BUGS
2470  if (arithmetic::internal::Real_precision_check_enabled)
2471  assert(mpfr_get_prec(r.d_value) == mpfr_get_prec(a.d_value));
2472  #endif
2473  mpfr_add_si(r.d_value, a.d_value, b, MPFR_RNDN);
2474  }
2475 
2476  inline friend void add_d(Real & r, const Real & a, double b)
2477  // Internal for expression templates
2478  {
2479  #ifdef PLLL_INTERNAL__BIGINT__HELP_FINDING_PRECISION_BUGS
2480  if (arithmetic::internal::Real_precision_check_enabled)
2481  assert(mpfr_get_prec(r.d_value) == mpfr_get_prec(a.d_value));
2482  #endif
2483  mpfr_add_d(r.d_value, a.d_value, b, MPFR_RNDN);
2484  }
2485 
2486  inline friend void add_z(Real & r, const Real & a, const Integer & b)
2487  // Internal for expression templates
2488  {
2489  #ifdef PLLL_INTERNAL__BIGINT__HELP_FINDING_PRECISION_BUGS
2490  if (arithmetic::internal::Real_precision_check_enabled)
2491  assert(mpfr_get_prec(r.d_value) == mpfr_get_prec(a.d_value));
2492  #endif
2493  mpfr_add_z(r.d_value, a.d_value, b.getInternal(), MPFR_RNDN);
2494  }
2495 
2496  inline friend void sub(Real & r, const Real & a, const Real & b)
2497  {
2498  #ifdef PLLL_INTERNAL__BIGINT__HELP_FINDING_PRECISION_BUGS
2499  if (arithmetic::internal::Real_precision_check_enabled)
2500  {
2501  assert(mpfr_get_prec(r.d_value) == mpfr_get_prec(a.d_value));
2502  assert(mpfr_get_prec(r.d_value) == mpfr_get_prec(b.d_value));
2503  }
2504  #endif
2505  mpfr_sub(r.d_value, a.d_value, b.d_value, MPFR_RNDN);
2506  }
2507 
2508  inline friend void sub_ui(Real & r, const Real & a, unsigned long b)
2509  // Internal for expression templates
2510  {
2511  #ifdef PLLL_INTERNAL__BIGINT__HELP_FINDING_PRECISION_BUGS
2512  if (arithmetic::internal::Real_precision_check_enabled)
2513  assert(mpfr_get_prec(r.d_value) == mpfr_get_prec(a.d_value));
2514  #endif
2515  mpfr_sub_ui(r.d_value, a.d_value, b, MPFR_RNDN);
2516  }
2517 
2518  inline friend void sub_si(Real & r, const Real & a, signed long b)
2519  // Internal for expression templates
2520  {
2521  #ifdef PLLL_INTERNAL__BIGINT__HELP_FINDING_PRECISION_BUGS
2522  if (arithmetic::internal::Real_precision_check_enabled)
2523  assert(mpfr_get_prec(r.d_value) == mpfr_get_prec(a.d_value));
2524  #endif
2525  mpfr_sub_si(r.d_value, a.d_value, b, MPFR_RNDN);
2526  }
2527 
2528  inline friend void sub_d(Real & r, const Real & a, double b)
2529  // Internal for expression templates
2530  {
2531  #ifdef PLLL_INTERNAL__BIGINT__HELP_FINDING_PRECISION_BUGS
2532  if (arithmetic::internal::Real_precision_check_enabled)
2533  assert(mpfr_get_prec(r.d_value) == mpfr_get_prec(a.d_value));
2534  #endif
2535  mpfr_sub_d(r.d_value, a.d_value, b, MPFR_RNDN);
2536  }
2537 
2538  inline friend void sub_z(Real & r, const Real & a, const Integer & b)
2539  // Internal for expression templates
2540  {
2541  #ifdef PLLL_INTERNAL__BIGINT__HELP_FINDING_PRECISION_BUGS
2542  if (arithmetic::internal::Real_precision_check_enabled)
2543  assert(mpfr_get_prec(r.d_value) == mpfr_get_prec(a.d_value));
2544  #endif
2545  mpfr_sub_z(r.d_value, a.d_value, b.getInternal(), MPFR_RNDN);
2546  }
2547 
2548  inline friend void ui_sub(Real & r, unsigned long a, const Real & b)
2549  // Internal for expression templates
2550  {
2551  #ifdef PLLL_INTERNAL__BIGINT__HELP_FINDING_PRECISION_BUGS
2552  if (arithmetic::internal::Real_precision_check_enabled)
2553  assert(mpfr_get_prec(r.d_value) == mpfr_get_prec(b.d_value));
2554  #endif
2555  mpfr_ui_sub(r.d_value, a, b.d_value, MPFR_RNDN);
2556  }
2557 
2558  inline friend void si_sub(Real & r, signed long a, const Real & b)
2559  // Internal for expression templates
2560  {
2561  #ifdef PLLL_INTERNAL__BIGINT__HELP_FINDING_PRECISION_BUGS
2562  if (arithmetic::internal::Real_precision_check_enabled)
2563  assert(mpfr_get_prec(r.d_value) == mpfr_get_prec(b.d_value));
2564  #endif
2565  mpfr_si_sub(r.d_value, a, b.d_value, MPFR_RNDN);
2566  }
2567 
2568  inline friend void d_sub(Real & r, double a, const Real & b)
2569  // Internal for expression templates
2570  {
2571  #ifdef PLLL_INTERNAL__BIGINT__HELP_FINDING_PRECISION_BUGS
2572  if (arithmetic::internal::Real_precision_check_enabled)
2573  assert(mpfr_get_prec(r.d_value) == mpfr_get_prec(b.d_value));
2574  #endif
2575  mpfr_d_sub(r.d_value, a, b.d_value, MPFR_RNDN);
2576  }
2577 
2578  inline friend void z_sub(Real & r, const Integer & a, const Real & b)
2579  // Internal for expression templates
2580  {
2581  #ifdef PLLL_INTERNAL__BIGINT__HELP_FINDING_PRECISION_BUGS
2582  if (arithmetic::internal::Real_precision_check_enabled)
2583  assert(mpfr_get_prec(r.d_value) == mpfr_get_prec(b.d_value));
2584  #endif
2585  mpfr_z_sub(r.d_value, a.getInternal(), b.d_value, MPFR_RNDN);
2586  }
2587 
2588  inline friend void addmul(Real & r, const Real & a, const Real & b) // r += a * b
2589  {
2590  #ifdef PLLL_INTERNAL__BIGINT__HELP_FINDING_PRECISION_BUGS
2591  if (arithmetic::internal::Real_precision_check_enabled)
2592  {
2593  assert(mpfr_get_prec(r.d_value) == mpfr_get_prec(a.d_value));
2594  assert(mpfr_get_prec(r.d_value) == mpfr_get_prec(b.d_value));
2595  }
2596  #endif
2597  mpfr_fma(r.d_value, a.d_value, b.d_value, r.d_value, MPFR_RNDN);
2598  }
2599 
2600  inline friend void addmul4(Real & r, const Real & a, const Real & b, const Real & c) // r = a * b + c
2601  // Internal for expression templates
2602  {
2603  #ifdef PLLL_INTERNAL__BIGINT__HELP_FINDING_PRECISION_BUGS
2604  if (arithmetic::internal::Real_precision_check_enabled)
2605  {
2606  assert(mpfr_get_prec(r.d_value) == mpfr_get_prec(a.d_value));
2607  assert(mpfr_get_prec(r.d_value) == mpfr_get_prec(b.d_value));
2608  assert(mpfr_get_prec(r.d_value) == mpfr_get_prec(c.d_value));
2609  }
2610  #endif
2611  mpfr_fma(r.d_value, a.d_value, b.d_value, c.d_value, MPFR_RNDN);
2612  }
2613 
2614  inline friend void submul(Real & r, const Real & a, const Real & b) // r -= a * b
2615  {
2616  #ifdef PLLL_INTERNAL__BIGINT__HELP_FINDING_PRECISION_BUGS
2617  if (arithmetic::internal::Real_precision_check_enabled)
2618  {
2619  assert(mpfr_get_prec(r.d_value) == mpfr_get_prec(a.d_value));
2620  assert(mpfr_get_prec(r.d_value) == mpfr_get_prec(b.d_value));
2621  }
2622  #endif
2623  mpfr_fms(r.d_value, a.d_value, b.d_value, r.d_value, MPFR_RNDN);
2624  mpfr_neg(r.d_value, r.d_value, MPFR_RNDN);
2625  }
2626 
2627  inline friend void submul4(Real & r, const Real & a, const Real & b, const Real & c) // r = a * b - c
2628  // Internal for expression templates
2629  {
2630  #ifdef PLLL_INTERNAL__BIGINT__HELP_FINDING_PRECISION_BUGS
2631  if (arithmetic::internal::Real_precision_check_enabled)
2632  {
2633  assert(mpfr_get_prec(r.d_value) == mpfr_get_prec(a.d_value));
2634  assert(mpfr_get_prec(r.d_value) == mpfr_get_prec(b.d_value));
2635  assert(mpfr_get_prec(r.d_value) == mpfr_get_prec(c.d_value));
2636  }
2637  #endif
2638  mpfr_fms(r.d_value, a.d_value, b.d_value, c.d_value, MPFR_RNDN);
2639  }
2640 
2641  inline friend void mul(Real & r, const Real & a, const Real & b)
2642  {
2643  #ifdef PLLL_INTERNAL__BIGINT__HELP_FINDING_PRECISION_BUGS
2644  if (arithmetic::internal::Real_precision_check_enabled)
2645  {
2646  assert(mpfr_get_prec(r.d_value) == mpfr_get_prec(a.d_value));
2647  assert(mpfr_get_prec(r.d_value) == mpfr_get_prec(b.d_value));
2648  }
2649  #endif
2650  mpfr_mul(r.d_value, a.d_value, b.d_value, MPFR_RNDN);
2651  }
2652 
2653  inline friend void mul_ui(Real & r, const Real & a, unsigned long b)
2654  // Internal for expression templates
2655  {
2656  #ifdef PLLL_INTERNAL__BIGINT__HELP_FINDING_PRECISION_BUGS
2657  if (arithmetic::internal::Real_precision_check_enabled)
2658  assert(mpfr_get_prec(r.d_value) == mpfr_get_prec(a.d_value));
2659  #endif
2660  mpfr_mul_ui(r.d_value, a.d_value, b, MPFR_RNDN);
2661  }
2662 
2663  inline friend void mul_si(Real & r, const Real & a, signed long b)
2664  // Internal for expression templates
2665  {
2666  #ifdef PLLL_INTERNAL__BIGINT__HELP_FINDING_PRECISION_BUGS
2667  if (arithmetic::internal::Real_precision_check_enabled)
2668  assert(mpfr_get_prec(r.d_value) == mpfr_get_prec(a.d_value));
2669  #endif
2670  mpfr_mul_si(r.d_value, a.d_value, b, MPFR_RNDN);
2671  }
2672 
2673  inline friend void mul_d(Real & r, const Real & a, double b)
2674  // Internal for expression templates
2675  {
2676  #ifdef PLLL_INTERNAL__BIGINT__HELP_FINDING_PRECISION_BUGS
2677  if (arithmetic::internal::Real_precision_check_enabled)
2678  assert(mpfr_get_prec(r.d_value) == mpfr_get_prec(a.d_value));
2679  #endif
2680  mpfr_mul_d(r.d_value, a.d_value, b, MPFR_RNDN);
2681  }
2682 
2683  inline friend void mul_z(Real & r, const Real & a, const Integer & b)
2684  // Internal for expression templates
2685  {
2686  #ifdef PLLL_INTERNAL__BIGINT__HELP_FINDING_PRECISION_BUGS
2687  if (arithmetic::internal::Real_precision_check_enabled)
2688  assert(mpfr_get_prec(r.d_value) == mpfr_get_prec(a.d_value));
2689  #endif
2690  mpfr_mul_z(r.d_value, a.d_value, b.getInternal(), MPFR_RNDN);
2691  }
2692 
2693  inline friend void div(Real & r, const Real & a, const Real & b)
2694  {
2695  #ifdef PLLL_INTERNAL__BIGINT__HELP_FINDING_PRECISION_BUGS
2696  if (arithmetic::internal::Real_precision_check_enabled)
2697  {
2698  assert(mpfr_get_prec(r.d_value) == mpfr_get_prec(a.d_value));
2699  assert(mpfr_get_prec(r.d_value) == mpfr_get_prec(b.d_value));
2700  }
2701  #endif
2702  mpfr_div(r.d_value, a.d_value, b.d_value, MPFR_RNDN);
2703  }
2704 
2705  inline friend void div_ui(Real & r, const Real & a, unsigned long b)
2706  // Internal for expression templates
2707  {
2708  #ifdef PLLL_INTERNAL__BIGINT__HELP_FINDING_PRECISION_BUGS
2709  if (arithmetic::internal::Real_precision_check_enabled)
2710  assert(mpfr_get_prec(r.d_value) == mpfr_get_prec(a.d_value));
2711  #endif
2712  mpfr_div_ui(r.d_value, a.d_value, b, MPFR_RNDN);
2713  }
2714 
2715  inline friend void div_si(Real & r, const Real & a, signed long b)
2716  // Internal for expression templates
2717  {
2718  #ifdef PLLL_INTERNAL__BIGINT__HELP_FINDING_PRECISION_BUGS
2719  if (arithmetic::internal::Real_precision_check_enabled)
2720  assert(mpfr_get_prec(r.d_value) == mpfr_get_prec(a.d_value));
2721  #endif
2722  mpfr_div_si(r.d_value, a.d_value, b, MPFR_RNDN);
2723  }
2724 
2725  inline friend void div_d(Real & r, const Real & a, double b)
2726  // Internal for expression templates
2727  {
2728  #ifdef PLLL_INTERNAL__BIGINT__HELP_FINDING_PRECISION_BUGS
2729  if (arithmetic::internal::Real_precision_check_enabled)
2730  assert(mpfr_get_prec(r.d_value) == mpfr_get_prec(a.d_value));
2731  #endif
2732  mpfr_div_d(r.d_value, a.d_value, b, MPFR_RNDN);
2733  }
2734 
2735  inline friend void div_z(Real & r, const Real & a, const Integer & b)
2736  // Internal for expression templates
2737  {
2738  #ifdef PLLL_INTERNAL__BIGINT__HELP_FINDING_PRECISION_BUGS
2739  if (arithmetic::internal::Real_precision_check_enabled)
2740  assert(mpfr_get_prec(r.d_value) == mpfr_get_prec(a.d_value));
2741  #endif
2742  mpfr_div_z(r.d_value, a.d_value, b.getInternal(), MPFR_RNDN);
2743  }
2744 
2745  inline friend void ui_div(Real & r, unsigned long a, const Real & b)
2746  // Internal for expression templates
2747  {
2748  #ifdef PLLL_INTERNAL__BIGINT__HELP_FINDING_PRECISION_BUGS
2749  if (arithmetic::internal::Real_precision_check_enabled)
2750  assert(mpfr_get_prec(r.d_value) == mpfr_get_prec(b.d_value));
2751  #endif
2752  mpfr_ui_div(r.d_value, a, b.d_value, MPFR_RNDN);
2753  }
2754 
2755  inline friend void si_div(Real & r, signed long a, const Real & b)
2756  // Internal for expression templates
2757  {
2758  #ifdef PLLL_INTERNAL__BIGINT__HELP_FINDING_PRECISION_BUGS
2759  if (arithmetic::internal::Real_precision_check_enabled)
2760  assert(mpfr_get_prec(r.d_value) == mpfr_get_prec(b.d_value));
2761  #endif
2762  mpfr_si_div(r.d_value, a, b.d_value, MPFR_RNDN);
2763  }
2764 
2765  inline friend void d_div(Real & r, double a, const Real & b)
2766  // Internal for expression templates
2767  {
2768  #ifdef PLLL_INTERNAL__BIGINT__HELP_FINDING_PRECISION_BUGS
2769  if (arithmetic::internal::Real_precision_check_enabled)
2770  assert(mpfr_get_prec(r.d_value) == mpfr_get_prec(b.d_value));
2771  #endif
2772  mpfr_d_div(r.d_value, a, b.d_value, MPFR_RNDN);
2773  }
2774 
2775  inline friend void mod(Real & r, const Real & a, const Real & b)
2776  {
2777  #ifdef PLLL_INTERNAL__BIGINT__HELP_FINDING_PRECISION_BUGS
2778  if (arithmetic::internal::Real_precision_check_enabled)
2779  {
2780  assert(mpfr_get_prec(r.d_value) == mpfr_get_prec(a.d_value));
2781  assert(mpfr_get_prec(r.d_value) == mpfr_get_prec(b.d_value));
2782  }
2783  #endif
2784  mpfr_fmod(r.d_value, a.d_value, b.d_value, MPFR_RNDN);
2785  }
2786 
2787  inline friend void divmod(Real & q, Real & r, const Real & a, const Real & b)
2788  {
2789  #ifdef PLLL_INTERNAL__BIGINT__HELP_FINDING_PRECISION_BUGS
2790  if (arithmetic::internal::Real_precision_check_enabled)
2791  {
2792  assert(mpfr_get_prec(r.d_value) == mpfr_get_prec(a.d_value));
2793  assert(mpfr_get_prec(r.d_value) == mpfr_get_prec(b.d_value));
2794  assert(mpfr_get_prec(r.d_value) == mpfr_get_prec(q.d_value));
2795  }
2796  #endif
2797  if ((&r == &a) || (&r == &b))
2798  {
2799  if ((&q == &a) || (&q == &b) || (mpfr_get_prec(q.d_value) != mpfr_get_prec(r.d_value)))
2800  {
2801  mpfr_t tmp;
2802  mpfr_init2(tmp, mpfr_get_prec(r.d_value));
2803  mpfr_fmod(tmp, a.d_value, b.d_value, MPFR_RNDN);
2804  mpfr_fms(q.d_value, tmp, b.d_value, a.d_value, MPFR_RNDN);
2805  mpfr_neg(q.d_value, q.d_value, MPFR_RNDN);
2806  mpfr_swap(r.d_value, tmp);
2807  mpfr_clear(tmp);
2808  }
2809  else
2810  {
2811  mpfr_fmod(q.d_value, a.d_value, b.d_value, MPFR_RNDN);
2812  mpfr_fms(r.d_value, q.d_value, b.d_value, a.d_value, MPFR_RNDN);
2813  mpfr_neg(r.d_value, r.d_value, MPFR_RNDN);
2814  mpfr_swap(q.d_value, r.d_value);
2815  }
2816  }
2817  else
2818  {
2819  mpfr_fmod(r.d_value, a.d_value, b.d_value, MPFR_RNDN);
2820  mpfr_fms(q.d_value, r.d_value, b.d_value, a.d_value, MPFR_RNDN);
2821  mpfr_neg(q.d_value, q.d_value, MPFR_RNDN);
2822  }
2823  }
2824 
2825  inline friend void shl(Real & r, const Real & a, const Real & b)
2826  {
2827  #ifdef PLLL_INTERNAL__BIGINT__HELP_FINDING_PRECISION_BUGS
2828  if (arithmetic::internal::Real_precision_check_enabled)
2829  {
2830  assert(mpfr_get_prec(r.d_value) == mpfr_get_prec(a.d_value));
2831  assert(mpfr_get_prec(r.d_value) == mpfr_get_prec(b.d_value));
2832  }
2833  #endif
2834  mpfr_t tmp;
2835  mpfr_init2(tmp, mpfr_get_prec(r.d_value));
2836  mpfr_ui_pow(tmp, 2, b.d_value, MPFR_RNDN);
2837  mpfr_mul(r.d_value, a.d_value, tmp, MPFR_RNDN);
2838  mpfr_clear(tmp);
2839  }
2840 
2841  inline friend void shr(Real & r, const Real & a, const Real & b)
2842  {
2843  #ifdef PLLL_INTERNAL__BIGINT__HELP_FINDING_PRECISION_BUGS
2844  if (arithmetic::internal::Real_precision_check_enabled)
2845  {
2846  assert(mpfr_get_prec(r.d_value) == mpfr_get_prec(a.d_value));
2847  assert(mpfr_get_prec(r.d_value) == mpfr_get_prec(b.d_value));
2848  }
2849  #endif
2850  mpfr_t tmp;
2851  mpfr_init2(tmp, mpfr_get_prec(r.d_value));
2852  mpfr_ui_pow(tmp, 2, b.d_value, MPFR_RNDN);
2853  mpfr_div(r.d_value, a.d_value, tmp, MPFR_RNDN);
2854  mpfr_clear(tmp);
2855  }
2856 
2857  inline friend void shl(Real & r, const Real & a, long b)
2858  {
2859  #ifdef PLLL_INTERNAL__BIGINT__HELP_FINDING_PRECISION_BUGS
2860  if (arithmetic::internal::Real_precision_check_enabled)
2861  assert(mpfr_get_prec(r.d_value) == mpfr_get_prec(a.d_value));
2862  #endif
2863  mpfr_mul_2si(r.d_value, a.d_value, b, MPFR_RNDN);
2864  }
2865 
2866  inline friend void shr(Real & r, const Real & a, long b)
2867  {
2868  #ifdef PLLL_INTERNAL__BIGINT__HELP_FINDING_PRECISION_BUGS
2869  if (arithmetic::internal::Real_precision_check_enabled)
2870  assert(mpfr_get_prec(r.d_value) == mpfr_get_prec(a.d_value));
2871  #endif
2872  mpfr_div_2si(r.d_value, a.d_value, b, MPFR_RNDN);
2873  }
2874 
2875  inline friend void increment(Real & r, const Real & a)
2876  {
2877  #ifdef PLLL_INTERNAL__BIGINT__HELP_FINDING_PRECISION_BUGS
2878  if (arithmetic::internal::Real_precision_check_enabled)
2879  assert(mpfr_get_prec(r.d_value) == mpfr_get_prec(a.d_value));
2880  #endif
2881  mpfr_add_ui(r.d_value, a.d_value, 1, MPFR_RNDN);
2882  }
2883 
2884  inline friend void decrement(Real & r, const Real & a)
2885  {
2886  #ifdef PLLL_INTERNAL__BIGINT__HELP_FINDING_PRECISION_BUGS
2887  if (arithmetic::internal::Real_precision_check_enabled)
2888  assert(mpfr_get_prec(r.d_value) == mpfr_get_prec(a.d_value));
2889  #endif
2890  mpfr_sub_ui(r.d_value, a.d_value, 1, MPFR_RNDN);
2891  }
2892 
2893  inline friend void neg(Real & r, const Real & a)
2894  {
2895  #ifdef PLLL_INTERNAL__BIGINT__HELP_FINDING_PRECISION_BUGS
2896  if (arithmetic::internal::Real_precision_check_enabled)
2897  assert(mpfr_get_prec(r.d_value) == mpfr_get_prec(a.d_value));
2898  #endif
2899  mpfr_neg(r.d_value, a.d_value, MPFR_RNDN);
2900  }
2901 
2902  inline friend void abs(Real & r, const Real & a)
2903  {
2904  #ifdef PLLL_INTERNAL__BIGINT__HELP_FINDING_PRECISION_BUGS
2905  if (arithmetic::internal::Real_precision_check_enabled)
2906  assert(mpfr_get_prec(r.d_value) == mpfr_get_prec(a.d_value));
2907  #endif
2908  mpfr_abs(r.d_value, a.d_value, MPFR_RNDN);
2909  }
2910 
2911  inline friend void makeAbs(Real & a) PLLL_INTERNAL_NOTHROW_POSTFIX_INLINE
2912  {
2913  abs(a, a);
2914  }
2915 
2916  friend std::ostream & operator << (std::ostream & s, const Real & r);
2917  // Output to stream
2918 
2919  friend std::istream & operator >> (std::istream & s, Real & r);
2920  // Input from stream
2921 
2922  inline friend void setNaN(Real & r)
2923  {
2924  mpfr_set_nan(r.d_value);
2925  }
2926 
2927  inline friend void setInfinity(Real & r, bool sign)
2928  {
2929  mpfr_set_inf(r.d_value, sign ? 1 : -1);
2930  }
2931 
2932  inline friend void setZero(Real & r, bool sign)
2933  // Set to zero
2934  {
2935  #if (MPFR_VERSION <= 0x0204FF)
2936  mpfr_set_ui(r.d_value, 0, MPFR_RNDN);
2937  if (!sign)
2938  mpfr_neg(r.d_value, r.d_value, MPFR_RNDN);
2939  #else
2940  mpfr_set_zero(r.d_value, sign ? 1 : -1);
2941  #endif
2942  }
2943 
2944  inline friend void setOne(Real & r)
2945  // Set to one
2946  {
2947  mpfr_set_ui(r.d_value, 1, MPFR_RNDN);
2948  }
2949 
2950  inline friend int compare(const Real & a, const Real & b)
2951  // Tests whether the first real is < (-1), = (0) or > (1) than the second.
2952  {
2953  #ifdef PLLL_INTERNAL__BIGINT__HELP_FINDING_PRECISION_BUGS
2954  if (arithmetic::internal::Real_precision_check_enabled)
2955  assert(mpfr_get_prec(a.d_value) == mpfr_get_prec(b.d_value));
2956  #endif
2957  return mpfr_cmp(a.d_value, b.d_value);
2958  }
2959 
2960  inline friend int compare_ui(const Real & a, unsigned long b)
2961  // Internal for expression templates
2962  {
2963  return mpfr_cmp_ui(a.d_value, b);
2964  }
2965 
2966  inline friend int compare_si(const Real & a, signed long b)
2967  // Internal for expression templates
2968  {
2969  return mpfr_cmp_si(a.d_value, b);
2970  }
2971 
2972  inline friend int compare_d(const Real & a, double b)
2973  // Internal for expression templates
2974  {
2975  return mpfr_cmp_d(a.d_value, b);
2976  }
2977 
2978  inline friend int compare_ld(const Real & a, long double b)
2979  // Internal for expression templates
2980  {
2981  return mpfr_cmp_ld(a.d_value, b);
2982  }
2983 
2984  inline friend int compare_z(const Real & a, const Integer & b)
2985  // Internal for expression templates
2986  {
2987  return mpfr_cmp_z(a.d_value, b.getInternal());
2988  }
2989 
2990  inline friend int compare_ui2(const Real & a, unsigned long b, long exp) // compares with b*2^exp
2991  // Internal for expression templates
2992  {
2993  return mpfr_cmp_ui_2exp(a.d_value, b, exp);
2994  }
2995 
2996  inline friend int compare_si2(const Real & a, signed long b, long exp) // compares with b*2^exp
2997  // Internal for expression templates
2998  {
2999  return mpfr_cmp_si_2exp(a.d_value, b, exp);
3000  }
3001 
3002  inline friend int compareAbsValues(const Real & a, const Real & b)
3003  // Tests whether the absolute value of the first Real is < (-1), = (0) or > (1) than the
3004  // absolute value of the second Real.
3005  {
3006  #ifdef PLLL_INTERNAL__BIGINT__HELP_FINDING_PRECISION_BUGS
3007  if (arithmetic::internal::Real_precision_check_enabled)
3008  assert(mpfr_get_prec(a.d_value) == mpfr_get_prec(b.d_value));
3009  #endif
3010  return mpfr_cmpabs(a.d_value, b.d_value);
3011  }
3012 
3013  inline friend int sign(const Real & r) PLLL_INTERNAL_NOTHROW_POSTFIX_INLINE
3014  // Returns the sign (i.e. -1, 0, 1).
3015  {
3016  return mpfr_sgn(r.d_value);
3017  }
3018 
3019  inline friend void square(Real & r, const Real & a)
3020  {
3021  #ifdef PLLL_INTERNAL__BIGINT__HELP_FINDING_PRECISION_BUGS
3022  if (arithmetic::internal::Real_precision_check_enabled)
3023  assert(mpfr_get_prec(r.d_value) == mpfr_get_prec(a.d_value));
3024  #endif
3025  mpfr_sqr(r.d_value, a.d_value, MPFR_RNDN);
3026  }
3027 
3028  inline friend void sin(Real & res, const Real & a)
3029  {
3030  #ifdef PLLL_INTERNAL__BIGINT__HELP_FINDING_PRECISION_BUGS
3031  if (arithmetic::internal::Real_precision_check_enabled)
3032  assert(mpfr_get_prec(a.d_value) == mpfr_get_prec(res.d_value));
3033  #endif
3034  mpfr_sin(res.d_value, a.d_value, MPFR_RNDN);
3035  }
3036 
3037  inline friend void cos(Real & res, const Real & a)
3038  {
3039  #ifdef PLLL_INTERNAL__BIGINT__HELP_FINDING_PRECISION_BUGS
3040  if (arithmetic::internal::Real_precision_check_enabled)
3041  assert(mpfr_get_prec(a.d_value) == mpfr_get_prec(res.d_value));
3042  #endif
3043  mpfr_cos(res.d_value, a.d_value, MPFR_RNDN);
3044  }
3045 
3046  inline friend void tan(Real & res, const Real & a)
3047  {
3048  #ifdef PLLL_INTERNAL__BIGINT__HELP_FINDING_PRECISION_BUGS
3049  if (arithmetic::internal::Real_precision_check_enabled)
3050  assert(mpfr_get_prec(a.d_value) == mpfr_get_prec(res.d_value));
3051  #endif
3052  mpfr_tan(res.d_value, a.d_value, MPFR_RNDN);
3053  }
3054 
3055  inline friend void asin(Real & res, const Real & a)
3056  {
3057  #ifdef PLLL_INTERNAL__BIGINT__HELP_FINDING_PRECISION_BUGS
3058  if (arithmetic::internal::Real_precision_check_enabled)
3059  assert(mpfr_get_prec(a.d_value) == mpfr_get_prec(res.d_value));
3060  #endif
3061  mpfr_asin(res.d_value, a.d_value, MPFR_RNDN);
3062  }
3063 
3064  inline friend void acos(Real & res, const Real & a)
3065  {
3066  #ifdef PLLL_INTERNAL__BIGINT__HELP_FINDING_PRECISION_BUGS
3067  if (arithmetic::internal::Real_precision_check_enabled)
3068  assert(mpfr_get_prec(a.d_value) == mpfr_get_prec(res.d_value));
3069  #endif
3070  mpfr_acos(res.d_value, a.d_value, MPFR_RNDN);
3071  }
3072 
3073  inline friend void atan(Real & res, const Real & a)
3074  {
3075  #ifdef PLLL_INTERNAL__BIGINT__HELP_FINDING_PRECISION_BUGS
3076  if (arithmetic::internal::Real_precision_check_enabled)
3077  assert(mpfr_get_prec(a.d_value) == mpfr_get_prec(res.d_value));
3078  #endif
3079  mpfr_atan(res.d_value, a.d_value, MPFR_RNDN);
3080  }
3081 
3082  inline friend void atan2(Real & res, const Real & y, const Real & x)
3083  {
3084  #ifdef PLLL_INTERNAL__BIGINT__HELP_FINDING_PRECISION_BUGS
3085  if (arithmetic::internal::Real_precision_check_enabled)
3086  {
3087  assert(mpfr_get_prec(y.d_value) == mpfr_get_prec(res.d_value));
3088  assert(mpfr_get_prec(x.d_value) == mpfr_get_prec(res.d_value));
3089  }
3090  #endif
3091  mpfr_atan2(res.d_value, y.d_value, x.d_value, MPFR_RNDN);
3092  }
3093 
3094  inline friend void exp(Real & res, const Real & a)
3095  {
3096  #ifdef PLLL_INTERNAL__BIGINT__HELP_FINDING_PRECISION_BUGS
3097  if (arithmetic::internal::Real_precision_check_enabled)
3098  assert(mpfr_get_prec(a.d_value) == mpfr_get_prec(res.d_value));
3099  #endif
3100  mpfr_exp(res.d_value, a.d_value, MPFR_RNDN);
3101  }
3102 
3103  inline friend void log(Real & res, const Real & a)
3104  {
3105  #ifdef PLLL_INTERNAL__BIGINT__HELP_FINDING_PRECISION_BUGS
3106  if (arithmetic::internal::Real_precision_check_enabled)
3107  assert(mpfr_get_prec(a.d_value) == mpfr_get_prec(res.d_value));
3108  #endif
3109  mpfr_log(res.d_value, a.d_value, MPFR_RNDN);
3110  }
3111 
3112  inline friend void log2(Real & res, const Real & a)
3113  {
3114  #ifdef PLLL_INTERNAL__BIGINT__HELP_FINDING_PRECISION_BUGS
3115  if (arithmetic::internal::Real_precision_check_enabled)
3116  assert(mpfr_get_prec(a.d_value) == mpfr_get_prec(res.d_value));
3117  #endif
3118  mpfr_log2(res.d_value, a.d_value, MPFR_RNDN);
3119  }
3120 
3121  inline friend void log10(Real & res, const Real & a)
3122  {
3123  #ifdef PLLL_INTERNAL__BIGINT__HELP_FINDING_PRECISION_BUGS
3124  if (arithmetic::internal::Real_precision_check_enabled)
3125  assert(mpfr_get_prec(a.d_value) == mpfr_get_prec(res.d_value));
3126  #endif
3127  mpfr_log10(res.d_value, a.d_value, MPFR_RNDN);
3128  }
3129 
3130  inline friend void sqrt(Real & res, const Real & a)
3131  {
3132  #ifdef PLLL_INTERNAL__BIGINT__HELP_FINDING_PRECISION_BUGS
3133  if (arithmetic::internal::Real_precision_check_enabled)
3134  assert(mpfr_get_prec(a.d_value) == mpfr_get_prec(res.d_value));
3135  #endif
3136  mpfr_sqrt(res.d_value, a.d_value, MPFR_RNDN);
3137  }
3138 
3139  inline friend void gamma(Real & res, const Real & a)
3140  {
3141  #ifdef PLLL_INTERNAL__BIGINT__HELP_FINDING_PRECISION_BUGS
3142  if (arithmetic::internal::Real_precision_check_enabled)
3143  assert(mpfr_get_prec(a.d_value) == mpfr_get_prec(res.d_value));
3144  #endif
3145  mpfr_gamma(res.d_value, a.d_value, MPFR_RNDN);
3146  }
3147 
3148  inline friend void lgamma(Real & res, const Real & a)
3149  {
3150  #ifdef PLLL_INTERNAL__BIGINT__HELP_FINDING_PRECISION_BUGS
3151  if (arithmetic::internal::Real_precision_check_enabled)
3152  assert(mpfr_get_prec(a.d_value) == mpfr_get_prec(res.d_value));
3153  #endif
3154  int sign;
3155  mpfr_lgamma(res.d_value, &sign, a.d_value, MPFR_RNDN);
3156  }
3157 
3158  inline friend void lgamma(Real & res, int & sign, const Real & a)
3159  {
3160  #ifdef PLLL_INTERNAL__BIGINT__HELP_FINDING_PRECISION_BUGS
3161  if (arithmetic::internal::Real_precision_check_enabled)
3162  assert(mpfr_get_prec(a.d_value) == mpfr_get_prec(res.d_value));
3163  #endif
3164  mpfr_lgamma(res.d_value, &sign, a.d_value, MPFR_RNDN);
3165  }
3166 
3167  inline friend void power(Real & res, const Real & a, signed long b)
3168  {
3169  #ifdef PLLL_INTERNAL__BIGINT__HELP_FINDING_PRECISION_BUGS
3170  if (arithmetic::internal::Real_precision_check_enabled)
3171  assert(mpfr_get_prec(res.d_value) == mpfr_get_prec(a.d_value));
3172  #endif
3173  mpfr_pow_si(res.d_value, a.d_value, b, MPFR_RNDN);
3174  }
3175 
3176  inline friend void power(Real & res, const Real & a, unsigned long b)
3177  {
3178  #ifdef PLLL_INTERNAL__BIGINT__HELP_FINDING_PRECISION_BUGS
3179  if (arithmetic::internal::Real_precision_check_enabled)
3180  assert(mpfr_get_prec(res.d_value) == mpfr_get_prec(a.d_value));
3181  #endif
3182  mpfr_pow_ui(res.d_value, a.d_value, b, MPFR_RNDN);
3183  }
3184 
3185  inline friend void power(Real & res, const Real & a, const Integer & b)
3186  {
3187  #ifdef PLLL_INTERNAL__BIGINT__HELP_FINDING_PRECISION_BUGS
3188  if (arithmetic::internal::Real_precision_check_enabled)
3189  assert(mpfr_get_prec(res.d_value) == mpfr_get_prec(a.d_value));
3190  #endif
3191  mpfr_pow_z(res.d_value, a.d_value, b.d_value, MPFR_RNDN);
3192  }
3193 
3194  inline friend void power(Real & res, const Real & a, const Real & b)
3195  {
3196  #ifdef PLLL_INTERNAL__BIGINT__HELP_FINDING_PRECISION_BUGS
3197  if (arithmetic::internal::Real_precision_check_enabled)
3198  {
3199  assert(mpfr_get_prec(res.d_value) == mpfr_get_prec(a.d_value));
3200  assert(mpfr_get_prec(res.d_value) == mpfr_get_prec(b.d_value));
3201  }
3202  #endif
3203  mpfr_pow(res.d_value, a.d_value, b.d_value, MPFR_RNDN);
3204  }
3205 
3206  inline friend void arithmetic::swap(plll::arithmetic::Real &, plll::arithmetic::Real &) PLLL_INTERNAL_NOTHROW_POSTFIX_INLINE;
3207 
3215  inline long getApproxExponent() const PLLL_INTERNAL_NOTHROW_POSTFIX_INLINE
3216  {
3217  return (mpfr_zero_p(d_value) != 0) ? std::numeric_limits<long>::min() : mpfr_get_exp(d_value);
3218  }
3219 
3220  // These ones should only be used in very, very special and rare cases!
3221  const mpfr_t & getInternal() const PLLL_INTERNAL_NOTHROW_POSTFIX_INLINE { return d_value; }
3222  mpfr_t & getInternal() PLLL_INTERNAL_NOTHROW_POSTFIX_INLINE { return d_value; }
3223  };
3224 
3225  inline void swap(Integer & a, Integer & b) PLLL_INTERNAL_NOTHROW_POSTFIX_INLINE
3226  {
3227  mpz_swap(a.d_value, b.d_value);
3228  }
3229 
3230  // Internal for expression templates
3231  inline void add_ui(Real & r, const Real & a, unsigned long b);
3232  inline void add_si(Real & r, const Real & a, signed long b);
3233  inline void add_d(Real & r, const Real & a, double b);
3234  inline void add_z(Real & r, const Real & a, const Integer & b);
3235  inline void sub_ui(Real & r, const Real & a, unsigned long b);
3236  inline void sub_si(Real & r, const Real & a, signed long b);
3237  inline void sub_d(Real & r, const Real & a, double b);
3238  inline void sub_z(Real & r, const Real & a, const Integer & b);
3239  inline void ui_sub(Real & r, unsigned long a, const Real & b);
3240  inline void si_sub(Real & r, signed long a, const Real & b);
3241  inline void d_sub(Real & r, double a, const Real & b);
3242  inline void z_sub(Real & r, const Integer & a, const Real & b);
3243  inline void addmul4(Real & r, const Real & a, const Real & b, const Real & c); // r = a * b + c
3244  inline void submul4(Real & r, const Real & a, const Real & b, const Real & c); // r = a * b - c
3245  inline void mul_ui(Real & r, const Real & a, unsigned long b);
3246  inline void mul_si(Real & r, const Real & a, signed long b);
3247  inline void mul_d(Real & r, const Real & a, double b);
3248  inline void mul_z(Real & r, const Real & a, const Integer & b);
3249  inline void div_ui(Real & r, const Real & a, unsigned long b);
3250  inline void div_si(Real & r, const Real & a, signed long b);
3251  inline void div_d(Real & r, const Real & a, double b);
3252  inline void div_z(Real & r, const Real & a, const Integer & b);
3253  inline void ui_div(Real & r, unsigned long a, const Real & b);
3254  inline void si_div(Real & r, signed long a, const Real & b);
3255  inline void d_div(Real & r, double a, const Real & b);
3256  inline int compare_ui(const Real & a, unsigned long b);
3257  inline int compare_si(const Real & a, signed long b);
3258  inline int compare_d(const Real & a, double b);
3259  inline int compare_ld(const Real & a, long double b);
3260  inline int compare_z(const Real & a, const Integer & b);
3261  inline int compare_ui2(const Real & a, unsigned long b, long exp); // compares with b*2^exp
3262  inline int compare_si2(const Real & a, signed long b, long exp); // compares with b*2^exp
3263  }
3264 }
3265 
3266 #include "arithmetic-gmp-rops.hpp"
3267 
3268 namespace plll
3269 {
3270  namespace arithmetic
3271  {
3282  {
3283  // stores information on a random number generator
3284 
3285  private:
3286  void * d_state; // we hide the implementation
3287  Integer d_seed;
3288 
3289  public:
3294 
3299 
3304 
3312 
3318  Integer getSeed() const;
3327  void setSeed(const Integer & seed);
3328 
3335  void randomizeTime();
3336 
3353  void randomizeDevRandom(double goodness = 0.01);
3367  static Integer createSeed();
3373  void randomizeSeed();
3387  static void initializeSeeder(double goodness = 0.01);
3388 
3395  void random(Integer & res, const Integer & bound);
3396 
3403  Integer random(const Integer & bound);
3404 
3411  unsigned long random(unsigned long bound);
3412 
3419  void randomBits(void * ptr, unsigned long count);
3420 
3427  void randomBits(Integer & res, unsigned long bits);
3428 
3435  Integer randomBits(unsigned long bits);
3436 
3443  void randomLen(Integer & res, unsigned long bits);
3444 
3451  Integer randomLen(unsigned long bits);
3452 
3459  void randomUniform(Real & r);
3460 
3468  void randomUniform(Real & r,const RealContext & rc);
3469 
3476  inline Real randomUniform()
3477  {
3478  Real r;
3479  randomUniform(r);
3480  return r;
3481  }
3482 
3490  inline Real randomUniform(const RealContext & rc)
3491  {
3492  Real r(rc);
3493  randomUniform(r, rc);
3494  return r;
3495  }
3496  };
3497 
3499  {
3500  private:
3501  RandomNumberGenerator & d_rng;
3502 
3503  public:
3508  UniformRNG(RandomNumberGenerator & rng) PLLL_INTERNAL_NOTHROW_POSTFIX_INLINE
3509  : d_rng(rng)
3510  {
3511  }
3512 
3520  inline Real randomUniform(const RealContext & rc)
3521  {
3522  Real r(rc);
3523  randomUniform(r);
3524  return r;
3525  }
3526 
3533  inline void randomUniform(Real & r)
3534  {
3535  d_rng.randomUniform(r);
3536  }
3537  };
3538 
3539  inline Real RealContext::getEpsilon() const
3540  {
3541  Real r(*this);
3542  mpfr_set_ui_2exp(r.d_value, 1, 1 - getRealPrecision(), MPFR_RNDN);
3543  return r;
3544  }
3545 
3546  inline void RealContext::getEpsilon(Real & x) const
3547  {
3548  if ((unsigned long)mpfr_get_prec(x.d_value) != getRealPrecision())
3549  {
3550  mpfr_clear(x.d_value);
3551  mpfr_init2(x.d_value, getRealPrecision());
3552  }
3553  mpfr_set_ui_2exp(x.d_value, 1, 1 - getRealPrecision(), MPFR_RNDN);
3554  }
3555 
3556  inline Real RealContext::getPi() const
3557  {
3558  Real x(*this);
3559  getPi(x);
3560  return x;
3561  }
3562 
3563  inline void RealContext::getPi(Real & x) const
3564  {
3565  mpfr_const_pi(x.d_value, MPFR_RNDN);
3566  }
3567 
3568  inline Real RealContext::getEuler() const
3569  {
3570  Real x(*this);
3571  getEuler(x);
3572  return x;
3573  }
3574 
3575  inline void RealContext::getEuler(Real & x) const
3576  {
3577  mpfr_const_euler(x.d_value, MPFR_RNDN);
3578  }
3579 
3580  inline Real RealContext::getLog2() const
3581  {
3582  Real x(*this);
3583  getLog2(x);
3584  return x;
3585  }
3586 
3587  inline void RealContext::getLog2(Real & x) const
3588  {
3589  mpfr_const_log2(x.d_value, MPFR_RNDN);
3590  }
3591 
3593  {
3594  private:
3595  RandomNumberGenerator & d_rng;
3596 
3597  public:
3602  inline UniformRNG(RandomNumberGenerator & rng) PLLL_INTERNAL_NOTHROW_POSTFIX_INLINE
3603  : d_rng(rng)
3604  {
3605  }
3606 
3613  inline void random(Integer & res, const Integer & bound)
3614  {
3615  d_rng.random(res, bound);
3616  }
3617 
3625  inline Integer random(const Integer & bound, const IntegerContext & ic)
3626  {
3627  Integer res;
3628  random(res, bound);
3629  return res;
3630  }
3631 
3638  inline void randomBits(Integer & res, unsigned long bits)
3639  {
3640  d_rng.randomBits(res, bits);
3641  }
3642 
3650  inline Integer randomBits(unsigned long bits, const IntegerContext & ic)
3651  {
3652  Integer res;
3653  randomBits(res, bits);
3654  return res;
3655  }
3656 
3663  inline void randomLen(Integer & res, unsigned long bits) // returns a random integer x with 2^(bits-1) <= x < 2^bits
3664  {
3665  d_rng.randomLen(res, bits);
3666  }
3667 
3675  inline Integer randomLen(unsigned long bits, const IntegerContext & ic)
3676  {
3677  Integer res;
3678  randomLen(res, bits);
3679  return res;
3680  }
3681  };
3682 
3683  inline void swap(Real & a, Real & b) PLLL_INTERNAL_NOTHROW_POSTFIX_INLINE
3684  {
3685  mpfr_swap(a.d_value, b.d_value);
3686  }
3687  }
3688 }
3689 
3690 #include "arithmetic-gmp-conv.hpp"
3691 
3692 #endif
friend bool isNonPositive(const Real &r) PLLL_INTERNAL_NOTHROW_POSTFIX_INLINE
Tests the given plll::arithmetic::Real object for being negative or zero.
void randomLen(Integer &res, unsigned long bits)
Creates a random integer of a fixed bit length.
expressions::Expression< IntegerContext, std::pair< expressions::Wrapper< IntegerContext >, expressions::Wrapper< IntegerContext > >, expressions::FloorDivOp > floorDiv(const Integer &a, const Integer &b)
Computes and returns .
friend bool operator>(const Integer &a, const Integer &b)
Compares the current integer with the given one.
friend void mul(Real &r, const Real &a, const Real &b)
Multiplies a with b and stores the result in r.
void submul(Integer &r, const Integer &a, const Integer &b)
Multiplies a and b and subtracts the result from r.
Real(long long i, const RealContext &rc)
Creates a new floating point number from the given native integer with the given context's precision...
Real randomUniform(const RealContext &rc)
Creates and returns a uniformly distributed floating point number in the interval ...
void euclideanDivisionPos(Integer &q, Integer &r, const Integer &a, const Integer &b)
Computes an Euclidean Division of a by b.
expressions::Expression< RealContext, expressions::Wrapper< RealContext >, expressions::ExpOp > exp(const Real &i)
Returns the exponential function evaluated at the given floating point number.
friend void makeAbs(Real &a) PLLL_INTERNAL_NOTHROW_POSTFIX_INLINE
Makes the operand non-negative.
friend void sub(Real &r, const Real &a, const Real &b)
Subtracts b from a and stores the result in r.
RealContext & getThreadRealContext()
Retrieves a context for the current thread. The context is thread local and cannot be accessed by thi...
friend void div(Integer &r, const Integer &a, const Integer &b)
Divides a by b and stores the result in r.
Real(const Real &r, bool clone=true)
Creates a copy of the given floating point number.
Real(long long i)
Creates a new floating point number from the given native integer.
Real(unsigned long i, const RealContext &rc)
Creates a new floating point number from the given native integer with the given context's precision...
bool isZero(const Integer &) PLLL_INTERNAL_NOTHROW_POSTFIX_INLINE
Tests the given plll::arithmetic::Integer object for being zero.
friend void setbit(Integer &x, long n, bool value)
Sets the n-th bit of to value.
friend bool isPMTwo(const Integer &i) PLLL_INTERNAL_NOTHROW_POSTFIX_INLINE
Tests the given plll::arithmetic::Integer object for being two or minus two.
Real(long double d, const RealContext &rc)
Creates a new floating point number from the given native floating point number with the given contex...
Real(long i)
Creates a new floating point number from the given native integer.
friend bool isZero(const Real &r) PLLL_INTERNAL_NOTHROW_POSTFIX_INLINE
Tests the given plll::arithmetic::Real object for being zero.
friend void submul(Real &r, const Real &a, const Real &b)
Multiplies a and b and subtracts the result from r.
void initArithmeticThreadAllocators()
Initializes the local thread allocator for the current thread, and sets the GMP and MPFR allocators t...
Integer(signed long i)
Creates a arbitrary precision integer from the given native integer.
expressions::Expression< RealContext, expressions::Wrapper< RealContext >, expressions::ATanOp > atan(const Real &i)
Returns the arctangent of the given floating point number.
void randomUniform(Real &r)
Creates a uniformly distributed floating point number in the interval .
friend void setInfinity(Real &r, bool sign)
Sets the given floating point number to .
bool isPMTwo(const Integer &) PLLL_INTERNAL_NOTHROW_POSTFIX_INLINE
Tests the given plll::arithmetic::Integer object for being two or minus two.
friend bool isNegative(const Integer &i) PLLL_INTERNAL_NOTHROW_POSTFIX_INLINE
Tests the given plll::arithmetic::Integer object for being strictly negative.
Real(double d)
Creates a new floating point number from the given native floating point number.
void randomizeTime()
Uses the system's time to seed this random number generator.
friend bool isNegative(const Real &r) PLLL_INTERNAL_NOTHROW_POSTFIX_INLINE
Tests the given plll::arithmetic::Real object for being strictly negative.
friend void shr(Real &r, const Real &a, const Real &b)
Multiplies a by and stores the result in r.
friend bool operator<(const Integer &a, const Integer &b)
Compares the current integer with the given one.
friend bool operator<=(const Integer &a, const Integer &b)
Compares the current integer with the given one.
int bit(const Integer &x, long n) PLLL_INTERNAL_NOTHROW_POSTFIX_INLINE
Returns the n bit of in the usual binary representation.
void XGCD(Integer &r, Integer &a, Integer &b, const Integer &x, const Integer &y)
Computes the non-negative extended Greatest Common Divisior r of x and y.
int compare(const Integer &a, const Integer &b)
Compares the two integers.
friend bool isPositive(const Integer &i) PLLL_INTERNAL_NOTHROW_POSTFIX_INLINE
Tests the given plll::arithmetic::Integer object for being strictly positive.
bool isNegative(const Integer &) PLLL_INTERNAL_NOTHROW_POSTFIX_INLINE
Tests the given plll::arithmetic::Integer object for being strictly negative.
friend void sub(Integer &r, const Integer &a, const Integer &b)
Subtracts b from a and stores the result in r.
friend bool operator!=(const Real &a, const Real &b)
Compares the two floating point numbers a and b for inequality.
friend bool isNonNegative(const Real &r) PLLL_INTERNAL_NOTHROW_POSTFIX_INLINE
Tests the given plll::arithmetic::Real object for being positive or zero.
Real(long i, const RealContext &rc)
Creates a new floating point number from the given native integer with the given context's precision...
void setOne(Integer &)
Sets the given integer to one.
void shr(Integer &r, const Integer &a, long b)
Shifts a by b bits to the left and stores the result in r.
static Integer createSeed()
Creates a seed using an internal random number generator.
friend void abs(Real &r, const Real &a)
Takes the absolute value of a and stores the result in r.
RandomNumberGenerator & operator=(const RandomNumberGenerator &rng)
Copies the state of the given random number generator to the current one.
void bneg(Integer &r, const Integer &a)
Takes the bitwise complement of a and stores the result in r.
Integer & operator=(const Integer &i)
Assigns the integer i to the current integer.
friend bool operator>=(const Real &a, const Real &b)
Compares the two floating point numbers a and b.
expressions::Expression< IntegerContext, expressions::Wrapper< IntegerContext >, expressions::SqrtFloorOp > sqrtFloor(const Integer &i)
Computes and returns the floor of the square root of i.
static unsigned long getMinRealPrecision() PLLL_INTERNAL_NOTHROW_POSTFIX_INLINE
Returns the minimal possible precision for this context.
friend long floorOfLog2(const Integer &x) PLLL_INTERNAL_NOTHROW_POSTFIX_INLINE
Computes and returns .
Conversion definitions for integers and floating point numbers.
bool isOne(const Integer &) PLLL_INTERNAL_NOTHROW_POSTFIX_INLINE
Tests the given plll::arithmetic::Integer object for being one.
friend void setOne(Real &r)
Sets the given floating point number to one.
expressions::Expression< RealContext, expressions::Wrapper< RealContext >, expressions::TanOp > tan(const Real &i)
Returns the tangent of the given floating point number.
friend void floorDiv(Integer &r, const Integer &a, const Integer &b)
Computes and stores the result in r.
expressions::Expression< RealContext, expressions::Wrapper< RealContext >, expressions::GammaOp > gamma(const Real &i)
Returns the Gamma function evaluated at the given floating point number.
friend void cos(Real &res, const Real &a)
Computes the cosine of a and stores the result in res.
Integer(unsigned int i)
Creates a arbitrary precision integer from the given native integer.
Integer random(const Integer &bound, const IntegerContext &ic)
Creates and returns a random arbitrary precision integer in the range .
Operator definitions for floating point numbers.
expressions::Expression< IntegerContext, expressions::Wrapper< IntegerContext >, expressions::AbsOp > abs(const Integer &i)
Computes and returns the absolute value of i.
friend void shl(Integer &r, const Integer &a, long b)
Shifts a by b bits to the left and stores the result in r.
RealContext(long prec) PLLL_INTERNAL_NOTHROW_POSTFIX_INLINE
Creates a new real context with the given precision.
Operator definitions for integers.
Real(const Integer &i, const RealContext &rc)
Creates a new floating point number from the given arbitrary precision integer with the given context...
static unsigned long getMaxRealPrecision() PLLL_INTERNAL_NOTHROW_POSTFIX_INLINE
Returns the maximal possible precision for this context.
friend void bxor(Integer &r, const Integer &a, const Integer &b)
Computes the bitwise exclusive or of a and b and stores the result in r.
friend void log(Real &res, const Real &a)
Computes the natural logarithm of a and stores the result in res.
expressions::Expression< IntegerContext, std::pair< expressions::Wrapper< IntegerContext >, expressions::Wrapper< IntegerContext > >, expressions::LCMOp > LCM(const Integer &a, const Integer &b)
Computes and returns the non-negative Least Common Multiple of a and b.
RandomNumberGenerator()
Creates a new default initialized random number generator.
void randomBits(Integer &res, unsigned long bits)
Creates random bits.
friend void setNaN(Real &r)
Sets the given floating point number to Not a Number.
expressions::Expression< IntegerContext, std::pair< expressions::Wrapper< IntegerContext >, expressions::Wrapper< IntegerContext > >, expressions::CeilDivOp > ceilDiv(const Integer &a, const Integer &b)
Computes and returns .
friend void increment(Integer &r, const Integer &a)
Increments a by one and stores the result in r.
friend void decrement(Integer &r, const Integer &a)
Decrements a by one and stores the result in r.
unsigned long precision() const
Returns the precision of the expression. Only compiles if the expression supports this...
friend bool operator!=(const Integer &a, const Integer &b)
Compares the current integer with the given one for inequality.
long approxLog2(const Integer &x) PLLL_INTERNAL_NOTHROW_POSTFIX_INLINE
Quickly approximates and returns the approximation.
void random(Integer &res, const Integer &bound)
Creates a random arbitrary precision integer in the range .
friend void roundDiv(Integer &r, const Integer &a, const Integer &b)
Computes (rounding to the next integer) and stores the result in r.
friend void acos(Real &res, const Real &a)
Computes the arccosine of a and stores the result in res.
Real & operator=(const Real &r)
Assigns the given floating point number r to this floating point number.
expressions::Expression< RealContext, std::pair< expressions::Wrapper< RealContext >, expressions::Wrapper< RealContext > >, expressions::ATan2Op > atan2(const Real &y, const Real &x)
Returns the arctangent of , using the signs of x and y to determine the quadrant. ...
Real randomUniform()
Creates and returns a uniformly distributed floating point number in the interval ...
friend void mod(Real &r, const Real &a, const Real &b)
Takes the remainder of the division of a by b and stores it in r.
void randomUniform(Real &r)
Creates a uniformly distributed floating point number in the interval .
friend void abs(Integer &r, const Integer &a)
Takes the absolute value of a and stores the result in r.
arithmetic::Real Real
The floating point type.
expressions::Expression< RealContext, expressions::Wrapper< RealContext >, expressions::Log2Op > log2(const Real &i)
Returns the base-2 logarithm evaluated at the given floating point number.
friend void euclideanDivision(Integer &q, Integer &r, const Integer &a, const Integer &b)
Computes an Euclidean Division of a by b.
friend int compareAbsValues(const Real &a, const Real &b)
Compares the two floating point numbers in absolute value.
Integer(unsigned long i)
Creates a arbitrary precision integer from the given native integer.
friend void shl(Real &r, const Real &a, const Real &b)
Multiplies a by and stores the result in r.
void setZero(Integer &)
Sets the given integer to zero.
void setContext(const RealContext &rc)
Adjusts the precision of this floating point number to the given context's precision.
void setRealPrecision(unsigned long prec) PLLL_INTERNAL_NOTHROW_POSTFIX_INLINE
Sets the precision of this context.
Integer(const expressions::Expression< IntegerContext, A, O > &E, const IntegerContext &ic)
Creates an integer from the given integer expression.
friend bool operator==(const Integer &a, const Integer &b)
Compares the current integer with the given one for equality.
void mul(Integer &r, const Integer &a, const Integer &b)
Multiplies a with b and stores the result in r.
Provides conversion implementation from type SourceType to DestContext::Type.
Definition: arithmetic.hpp:713
void div(Integer &r, const Integer &a, const Integer &b)
Divides a by b and stores the result in r.
friend void log10(Real &res, const Real &a)
Computes the logarithm of a to base 10 and stores the result in res.
friend void divmod(Integer &q, Integer &r, const Integer &a, const Integer &b)
Stores quotient and remainder of the division of a by b in q respectively r.
void setNaN(Real &)
Sets the given floating point number to Not a Number.
Real(const RealContext &rc)
Creates a real with the precision given by the context.
friend void ceilDiv(Integer &r, const Integer &a, const Integer &b)
Computes and stores the result in r.
static void setContext(const IntegerContext &c)
Sets the integer context c.
friend std::istream & operator>>(std::istream &s, Integer &i)
Reads the integer from the given input stream.
friend void neg(Real &r, const Real &a)
Negates a and stores the result in r.
Real(unsigned long i)
Creates a new floating point number from the given native integer.
friend bool isNonNegative(const Integer &i) PLLL_INTERNAL_NOTHROW_POSTFIX_INLINE
Tests the given plll::arithmetic::Integer object for being positive or zero.
Provides facilities to convert strings to types.
Real getPi() const
Returns an approximation of for the current context.
friend void sin(Real &res, const Real &a)
Computes the sine of a and stores the result in res.
long getApproxExponent() const PLLL_INTERNAL_NOTHROW_POSTFIX_INLINE
Returns approximate e such that |x| is approximately .
Integer randomBits(unsigned long bits, const IntegerContext &ic)
Creates random bits.
Real(const expressions::Expression< RealContext, A, O > &E, const RealContext &rc)
Creates a floating point number from the given floating point expression and Real context...
friend bool isOne(const Integer &i) PLLL_INTERNAL_NOTHROW_POSTFIX_INLINE
Tests the given plll::arithmetic::Integer object for being one.
friend bool operator>=(const Integer &a, const Integer &b)
Compares the current integer with the given one.
friend void bor(Integer &r, const Integer &a, const Integer &b)
Computes the bitwise or of a and b and stores the result in r.
friend void atan(Real &res, const Real &a)
Computes the arctangent of a and stores the result in res.
friend std::ostream & operator<<(std::ostream &s, const Integer &i)
Outputs the integer on the given output stream.
expressions::Expression< RealContext, expressions::Wrapper< RealContext >, expressions::LogOp > log(const Real &i)
Returns the natural logarithm evaluated at the given floating point number.
void mod(Integer &r, const Integer &a, const Integer &b)
Takes the remainder of the division of a by b and stores it in r.
void increment(Integer &r, const Integer &a)
Increments a by one and stores the result in r.
friend std::istream & operator>>(std::istream &s, Real &r)
Reads the floating point number from the given input stream.
static void initializeSeeder(double goodness=0.01)
Calls randomizeDevRandom(goodness) for the internal random number generator which is used for createS...
void setSeed(const Integer &seed)
Sets a new seed for the generator.
Real(const expressions::Expression< RealContext, A, O > &E)
Creates a floating point number from the given floating point expression.
friend void square(Real &r, const Real &a)
Computes the square of a and stores the result in r.
friend void add(Real &r, const Real &a, const Real &b)
Adds a and b and stores the result in r.
Provides facilities to convert types to std::strings.
friend void mod(Integer &r, const Integer &a, const Integer &b)
Takes the remainder of the division of a by b and stores it in r.
friend void gamma(Real &res, const Real &a)
Computes the Gamma function at a and stores the result in res.
friend void bneg(Integer &r, const Integer &a)
Takes the bitwise complement of a and stores the result in r.
friend bool operator==(const Real &a, const Real &b)
Compares the two floating point numbers a and b for equality.
Integer(const Integer &i)
Creates a copy of the given integer.
friend void neg(Integer &r, const Integer &a)
Negates a and stores the result in r.
void random(Integer &res, const Integer &bound)
Creates a random arbitrary precision integer in the range .
~Real() PLLL_INTERNAL_NOTHROW_POSTFIX_INLINE
Releases the memory used by the arbitrary precision floating point number.
friend int compare(const Real &a, const Real &b)
Compares the two floating point numbers.
friend void tan(Real &res, const Real &a)
Computes the tangent of a and stores the result in res.
Real(double d, const RealContext &rc)
Creates a new floating point number from the given native floating point number with the given contex...
friend void euclideanDivisionPos(Integer &q, Integer &r, const Integer &a, const Integer &b)
Computes an Euclidean Division of a by b.
friend void setZero(Real &r, bool sign)
Sets the given floating point number to .
unsigned long precision() const PLLL_INTERNAL_NOTHROW_POSTFIX_INLINE
Retrieves the precision of this floating point number.
RealContext Context
The context type.
Implementation backend for conversions from context types to native types.
Definition: arithmetic.hpp:994
Integer(signed int i)
Creates a arbitrary precision integer from the given native integer.
friend void div(Real &r, const Real &a, const Real &b)
Divides a by b and stores the result in r.
~Integer() PLLL_INTERNAL_NOTHROW_POSTFIX_INLINE
Releases the memory used by the arbitrary precision integer.
friend bool isOne(const Real &r) PLLL_INTERNAL_NOTHROW_POSTFIX_INLINE
Tests the given plll::arithmetic::Real object for being one.
arithmetic::Integer Type
The integer type.
Represents a random number generator.
friend long bitLength(const Integer &x) PLLL_INTERNAL_NOTHROW_POSTFIX_INLINE
Computes and returns n such that .
friend void submul(Integer &r, const Integer &a, const Integer &b)
Multiplies a and b and subtracts the result from r.
void swap(plll::arithmetic::Integer &, plll::arithmetic::Integer &) PLLL_INTERNAL_NOTHROW_POSTFIX_INLINE
Swaps two plll::arithmetic::Integer objects.
void bor(Integer &r, const Integer &a, const Integer &b)
Computes the bitwise or of a and b and stores the result in r.
friend void power(Integer &r, const Integer &a, long b)
Raises a to the power b and stores the result in r.
friend int bit(const Integer &x, long n) PLLL_INTERNAL_NOTHROW_POSTFIX_INLINE
Returns the n bit of in the usual binary representation.
friend void band(Integer &r, const Integer &a, const Integer &b)
Computes the bitwise and of a and b and stores the result in r.
friend void sqrtCeil(Integer &r, const Integer &a)
Computes and stores the result in r.
~RandomNumberGenerator()
Releases the state for this random number generator.
expressions::Expression< IntegerContext, std::pair< expressions::Wrapper< IntegerContext >, expressions::Wrapper< IntegerContext > >, expressions::PowerOp > power(const Integer &a, const Integer &b)
Computes and returns a raised to the power of b.
void randomLen(Integer &res, unsigned long bits)
Creates a random integer of a fixed bit length.
expressions::Expression< IntegerContext, expressions::Wrapper< IntegerContext >, expressions::SqrtCeilOp > sqrtCeil(const Integer &i)
Computes and returns the ceil of the square root of i.
expressions::Expression< RealContext, expressions::Wrapper< RealContext >, expressions::SinOp > sin(const Real &i)
Returns the sine of the given floating point number.
friend void atan2(Real &res, const Real &y, const Real &x)
Computes the arctangent of and stores the result inres. The signs ofxandy` are used to determine the ...
friend void makeAbs(Integer &a) PLLL_INTERNAL_NOTHROW_POSTFIX_INLINE
Makes the operand non-negative.
Integer(long long i)
Creates a arbitrary precision integer from the given native integer.
void setbit(Integer &x, long n, bool value=true)
Sets the n-th bit of to value.
friend void sqrtFloor(Integer &r, const Integer &a)
Computes and stores the result in r.
friend bool operator>(const Real &a, const Real &b)
Compares the two floating point numbers a and b.
void bxor(Integer &r, const Integer &a, const Integer &b)
Computes the bitwise exclusive or of a and b and stores the result in r.
expressions::Expression< RealContext, expressions::Wrapper< RealContext >, expressions::ASinOp > asin(const Real &i)
Returns the arcsine of the given floating point number.
Real(const Integer &i)
Creates a new floating point number from the given arbitrary precision integer.
friend void square(Integer &r, const Integer &a)
Computes the square of a and stores the result in r.
Real getEpsilon() const
Returns the machine constant for the current context.
expressions::Expression< RealContext, expressions::Wrapper< RealContext >, expressions::Log10Op > log10(const Real &i)
Returns the base-10 logarithm evaluated at the given floating point number.
friend int compare(const Integer &a, const Integer &b)
Compares the two integers.
expressions::Expression< RealContext, expressions::Wrapper< RealContext >, expressions::ACosOp > acos(const Real &i)
Returns the arccosine of the given floating point number.
int compareAbsValues(const Integer &a, const Integer &b)
Compares the two integers in absolute value.
friend void setOne(Integer &i)
Sets the given integer to one.
friend void add(Integer &r, const Integer &a, const Integer &b)
Adds a and b and stores the result in r.
Represents an arbitrary precision floating point value.
Integer()
Creates a new integer. Default value is zero.
bool isNonNegative(const Integer &) PLLL_INTERNAL_NOTHROW_POSTFIX_INLINE
Tests the given plll::arithmetic::Integer object for being positive or zero.
expressions::Expression< IntegerContext, std::pair< expressions::Wrapper< IntegerContext >, expressions::Wrapper< IntegerContext > >, expressions::RoundDivOp > roundDiv(const Integer &a, const Integer &b)
Computes and returns .
Integer getSeed() const
Retrieves the last set seed of the generator.
Integer(const IntegerContext &c)
Creates a new integer. Default value is zero.
friend RealContext & getThreadRealContext()
Retrieves a context for the current thread. The context is thread local and cannot be accessed by thi...
friend bool operator<(const Real &a, const Real &b)
Compares the two floating point numbers a and b.
int sign(const Integer &) PLLL_INTERNAL_NOTHROW_POSTFIX_INLINE
Returns the sign of the given integer.
RealContext() PLLL_INTERNAL_NOTHROW_POSTFIX_INLINE
Creates a new real context with the current global default precision.
Real(const Real &r, const RealContext &rc)
Creates a copy of the given floating point number with the given context's precision.
friend void XGCD(Integer &r, Integer &a, Integer &b, const Integer &x, const Integer &y)
Computes the non-negative extended Greatest Common Divisior r of x and y.
friend std::ostream & operator<<(std::ostream &s, const Real &r)
Outputs the floating point number on the given output stream.
Helper templates.
void shl(Integer &r, const Integer &a, long b)
Shifts a by b bits to the left and stores the result in r.
UniformRNG(RandomNumberGenerator &rng) PLLL_INTERNAL_NOTHROW_POSTFIX_INLINE
Creates a new uniform random number generator based on the given random number generator.
void band(Integer &r, const Integer &a, const Integer &b)
Computes the bitwise and of a and b and stores the result in r.
expressions::Expression< RealContext, expressions::Wrapper< RealContext >, expressions::CosOp > cos(const Real &i)
Returns the cosine of the given floating point number.
friend void increment(Real &r, const Real &a)
Increments a by one and stores the result in r.
arithmetic::Integer Integer
The integer type.
Represents an arithmetic context for arbitrary precision floating point values.
friend bool isPMOne(const Integer &i) PLLL_INTERNAL_NOTHROW_POSTFIX_INLINE
Tests the given plll::arithmetic::Integer object for being one or minus one.
void neg(Integer &r, const Integer &a)
Negates a and stores the result in r.
friend void exp(Real &res, const Real &a)
Computes the exponential function at a and stores the result in res.
friend void divmod(Real &q, Real &r, const Real &a, const Real &b)
Stores quotient and remainder of the division of a by b in q respectively r.
void addmul(Integer &r, const Integer &a, const Integer &b)
Multiplies a and b and adds the result to r.
friend void lgamma(Real &res, const Real &a)
Computes the logarithm of the absolute value of the Gamma function at a and stores the result in res...
bool isPositive(const Integer &) PLLL_INTERNAL_NOTHROW_POSTFIX_INLINE
Tests the given plll::arithmetic::Integer object for being strictly positive.
friend void setZero(Integer &i)
Sets the given integer to zero.
Integer(double d)
Creates a arbitrary precision integer from the given native floating point number.
void divmod(Integer &q, Integer &r, const Integer &a, const Integer &b)
Stores quotient and remainder of the division of a by b in q respectively r.
Integer(const Integer &i, const IntegerContext &ic)
Creates a copy of the given integer.
void add(Integer &r, const Integer &a, const Integer &b)
Adds a and b and stores the result in r.
arithmetic::Real Type
The floating point type.
Real getLog2() const
Returns an approximation of the natural logarithm for the current context.
friend void LCM(Integer &r, const Integer &x, const Integer &y)
Computes the non-negative Least Common Multiple r of x and y.
void makeAbs(Integer &a) PLLL_INTERNAL_NOTHROW_POSTFIX_INLINE
Makes the operand non-negative.
expressions::Expression< IntegerContext, expressions::Wrapper< IntegerContext >, expressions::SquareOp > square(const Integer &i)
Computes and returns the square of i.
void decrement(Integer &r, const Integer &a)
Decrements a by one and stores the result in r.
long bitLength(const Integer &x) PLLL_INTERNAL_NOTHROW_POSTFIX_INLINE
Computes and returns n such that .
friend int sign(const Real &r) PLLL_INTERNAL_NOTHROW_POSTFIX_INLINE
Returns the sign of the given floating point number.
friend void addmul(Integer &r, const Integer &a, const Integer &b)
Multiplies a and b and adds the result to r.
void randomizeDevRandom(double goodness=0.01)
Uses the operating system's random number generator to initialize this random number generator...
long floorOfLog2(const Integer &x) PLLL_INTERNAL_NOTHROW_POSTFIX_INLINE
Computes and returns .
IntegerContext Context
The context type.
friend void shr(Integer &r, const Integer &a, long b)
Shifts a by b bits to the left and stores the result in r.
Real()
Creates a new floating point number.
Integer(long double d)
Creates a arbitrary precision integer from the given native floating point number.
bool isNonPositive(const Integer &) PLLL_INTERNAL_NOTHROW_POSTFIX_INLINE
Tests the given plll::arithmetic::Integer object for being negative or zero.
friend int sign(const Integer &i) PLLL_INTERNAL_NOTHROW_POSTFIX_INLINE
Returns the sign of the given integer.
long ceilOfLog2(const Integer &x) PLLL_INTERNAL_NOTHROW_POSTFIX_INLINE
Computes and returns .
friend int compareAbsValues(const Integer &a, const Integer &b)
Compares the two integers in absolute value.
Integer(const expressions::Expression< IntegerContext, A, O > &E)
Creates an integer from the given integer expression.
void setInfinity(Real &r, bool sign=true)
Sets the given floating point number to .
friend void mul(Integer &r, const Integer &a, const Integer &b)
Multiplies a with b and stores the result in r.
Real getEuler() const
Returns an approximation of the Euler number for the current context.
unsigned long getRealPrecision() const PLLL_INTERNAL_NOTHROW_POSTFIX_INLINE
Returns the precision of this context.
friend void decrement(Real &r, const Real &a)
Decrements a by one and stores the result in r.
friend void log2(Real &res, const Real &a)
Computes the logarithm of a to base 2 and stores the result in res.
friend long ceilOfLog2(const Integer &x) PLLL_INTERNAL_NOTHROW_POSTFIX_INLINE
Computes and returns .
Represents an arbitrary precision integer.
expressions::Expression< RealContext, expressions::Wrapper< RealContext >, expressions::SqrtOp > sqrt(const Real &i)
Returns the square root of the given floating point number.
void randomizeSeed()
Initializes this random number generator with a random seed.
friend void GCD(Integer &r, const Integer &x, const Integer &y)
Computes the non-negative Greatest Common Divisior r of x and y.
void assignTo(typename Context::Type &x) const
Evaluates the expression into the given object.
friend bool isNonPositive(const Integer &i) PLLL_INTERNAL_NOTHROW_POSTFIX_INLINE
Tests the given plll::arithmetic::Integer object for being negative or zero.
friend void sqrt(Real &res, const Real &a)
Computes the square root of a and stores the result in res.
expressions::Expression< RealContext, expressions::Wrapper< RealContext >, expressions::LGammaOp > lgamma(const Real &i)
Returns the natural logarithm of the absolute value of the Gamma function evaluated at the given floa...
bool isPMOne(const Integer &) PLLL_INTERNAL_NOTHROW_POSTFIX_INLINE
Tests the given plll::arithmetic::Integer object for being one or minus one.
void euclideanDivision(Integer &q, Integer &r, const Integer &a, const Integer &b)
Computes an Euclidean Division of a by b.
friend long approxLog2(const Integer &x) PLLL_INTERNAL_NOTHROW_POSTFIX_INLINE
Quickly approximates and returns the approximation.
friend bool isZero(const Integer &i) PLLL_INTERNAL_NOTHROW_POSTFIX_INLINE
Tests the given plll::arithmetic::Integer object for being zero.
Real randomUniform(const RealContext &rc)
Creates and returns a uniformly distributed floating point number in the interval ...
UniformRNG(RandomNumberGenerator &rng) PLLL_INTERNAL_NOTHROW_POSTFIX_INLINE
Creates a new uniform random number generator based on the given random number generator.
Integer randomLen(unsigned long bits, const IntegerContext &ic)
Creates a random integer of a fixed bit length.
expressions::Expression< IntegerContext, std::pair< expressions::Wrapper< IntegerContext >, expressions::Wrapper< IntegerContext > >, expressions::GCDOp > GCD(const Integer &a, const Integer &b)
Computes and returns the non-negative Greatest Common Divisor of a and b.
friend bool isPositive(const Real &r) PLLL_INTERNAL_NOTHROW_POSTFIX_INLINE
Tests the given plll::arithmetic::Real object for being strictly positive.
friend void addmul(Real &r, const Real &a, const Real &b)
Multiplies a and b and adds the result to r.
void randomBits(void *ptr, unsigned long count)
Writes a given number of random bytes to the memory location pointed to.
Real(long double d)
Creates a new floating point number from the given native floating point number.
friend bool operator<=(const Real &a, const Real &b)
Compares the two floating point numbers a and b.
Represents an arithmetic context for arbitrary precision integer.
friend void asin(Real &res, const Real &a)
Computes the arcsine of a and stores the result in res.
void sub(Integer &r, const Integer &a, const Integer &b)
Subtracts b from a and stores the result in r.