integer.cpp
1 #include <symengine/rational.h>
2 #include <symengine/pow.h>
3 #include <symengine/symengine_exception.h>
4 #include <symengine/symengine_casts.h>
5 
6 namespace SymEngine
7 {
8 
9 hash_t Integer::__hash__() const
10 {
11  // only the least significant bits that fit into "long long int" are
12  // hashed:
13  return ((hash_t)mp_get_ui(this->i)) * (hash_t)(mp_sign(this->i));
14 }
15 
16 bool Integer::__eq__(const Basic &o) const
17 {
18  if (is_a<Integer>(o)) {
19  const Integer &s = down_cast<const Integer &>(o);
20  return this->i == s.i;
21  }
22  return false;
23 }
24 
25 int Integer::compare(const Basic &o) const
26 {
27  SYMENGINE_ASSERT(is_a<Integer>(o))
28  const Integer &s = down_cast<const Integer &>(o);
29  if (i == s.i)
30  return 0;
31  return i < s.i ? -1 : 1;
32 }
33 
34 signed long int Integer::as_int() const
35 {
36  // mp_get_si() returns "signed long int", so that's what we return from
37  // "as_int()" and we leave it to the user to do any possible further integer
38  // conversions.
39  if (not(mp_fits_slong_p(this->i))) {
40  throw SymEngineException("as_int: Integer larger than int");
41  }
42  return mp_get_si(this->i);
43 }
44 
45 unsigned long int Integer::as_uint() const
46 {
47  // mp_get_ui() returns "unsigned long int", so that's what we return from
48  // "as_uint()" and we leave it to the user to do any possible further
49  // integer
50  // conversions.
51  if (this->i < 0u) {
52  throw SymEngineException("as_uint: negative Integer");
53  }
54  if (not(mp_fits_ulong_p(this->i))) {
55  throw SymEngineException("as_uint: Integer larger than uint");
56  }
57  return mp_get_ui(this->i);
58 }
59 
60 RCP<const Number> Integer::divint(const Integer &other) const
61 {
62  if (other.i == 0) {
63  if (this->i == 0) {
64  return Nan;
65  } else {
66  return ComplexInf;
67  }
68  }
69  rational_class q(this->i, other.i);
70 
71  // This is potentially slow, but has to be done, since q might not
72  // be in canonical form.
73  canonicalize(q);
74 
75  return Rational::from_mpq(std::move(q));
76 }
77 
78 RCP<const Number> Integer::rdiv(const Number &other) const
79 {
80  if (is_a<Integer>(other)) {
81  if (this->i == 0) {
82  if (other.is_zero()) {
83  return Nan;
84  } else {
85  return ComplexInf;
86  }
87  }
88  rational_class q((down_cast<const Integer &>(other)).i, this->i);
89 
90  // This is potentially slow, but has to be done, since q might not
91  // be in canonical form.
92  canonicalize(q);
93 
94  return Rational::from_mpq(std::move(q));
95  } else {
96  throw NotImplementedError("Not Implemented");
97  }
98 }
99 
100 RCP<const Number> Integer::pow_negint(const Integer &other) const
101 {
102  RCP<const Number> tmp = powint(*other.neg());
103  if (is_a<Integer>(*tmp)) {
104  const integer_class &j = down_cast<const Integer &>(*tmp).i;
105 #if SYMENGINE_INTEGER_CLASS == SYMENGINE_BOOSTMP
106  // boost::multiprecision::cpp_rational lacks an (int, cpp_int)
107  // constructor. must use cpp_rational(cpp_int,cpp_int)
108  rational_class q(integer_class(mp_sign(j)), mp_abs(j));
109 #else
110  rational_class q(mp_sign(j), mp_abs(j));
111 #endif
112  return Rational::from_mpq(std::move(q));
113  } else {
114  throw SymEngineException("powint returned non-integer");
115  }
116 }
117 
118 RCP<const Integer> isqrt(const Integer &n)
119 {
120  return integer(mp_sqrt(n.as_integer_class()));
121 }
122 
123 RCP<const Integer> iabs(const Integer &n)
124 {
125  return integer(mp_abs(n.as_integer_class()));
126 }
127 
128 int i_nth_root(const Ptr<RCP<const Integer>> &r, const Integer &a,
129  unsigned long int n)
130 {
131  if (n == 0)
132  throw SymEngineException("i_nth_root: Can not find Zeroth root");
133 
134  int ret_val;
135  integer_class t;
136 
137  ret_val = mp_root(t, a.as_integer_class(), n);
138  *r = integer(std::move(t));
139 
140  return ret_val;
141 }
142 
143 bool perfect_square(const Integer &n)
144 {
145  return mp_perfect_square_p(n.as_integer_class());
146 }
147 
148 bool perfect_power(const Integer &n)
149 {
150  return mp_perfect_power_p(n.as_integer_class());
151 }
152 
153 } // namespace SymEngine
The lowest unit of symbolic representation.
Definition: basic.h:95
Integer Class.
Definition: integer.h:19
unsigned long int as_uint() const
Convert to uint, raise an exception if it does not fit.
Definition: integer.cpp:45
virtual hash_t __hash__() const
Definition: integer.cpp:9
virtual bool __eq__(const Basic &o) const
Definition: integer.cpp:16
const integer_class & as_integer_class() const
Convert to integer_class.
Definition: integer.h:48
virtual int compare(const Basic &o) const
Definition: integer.cpp:25
RCP< const Number > divint(const Integer &other) const
Integer Division.
Definition: integer.cpp:60
RCP< const Number > pow_negint(const Integer &other) const
Fast Negative Power Evaluation.
Definition: integer.cpp:100
RCP< const Integer > neg() const
Definition: integer.h:119
signed long int as_int() const
Convert to int, raise an exception if it does not fit.
Definition: integer.cpp:34
RCP< const Number > powint(const Integer &other) const
Fast Power Evaluation.
Definition: integer.h:105
integer_class i
i : object of integer_class
Definition: integer.h:22
virtual bool is_zero() const =0
static RCP< const Number > from_mpq(const rational_class &i)
Definition: rational.cpp:23
T move(T... args)
Main namespace for SymEngine package.
Definition: add.cpp:19
std::enable_if< std::is_integral< T >::value, RCP< const Integer > >::type integer(T i)
Definition: integer.h:200
RCP< const Integer > isqrt(const Integer &n)
Integer Square root.
Definition: integer.cpp:118
bool perfect_square(const Integer &n)
Perfect Square.
Definition: integer.cpp:143
bool perfect_power(const Integer &n)
Perfect Square.
Definition: integer.cpp:148
int i_nth_root(const Ptr< RCP< const Integer >> &r, const Integer &a, unsigned long int n)
Integer nth root.
Definition: integer.cpp:128
RCP< const Integer > iabs(const Integer &n)
Integer Absolute value.
Definition: integer.cpp:123