Program Listing for File integer.h¶
↰ Return to documentation for file (symengine/symengine/integer.h
)
#ifndef SYMENGINE_INTEGER_H
#define SYMENGINE_INTEGER_H
#include <symengine/number.h>
#include <symengine/symengine_exception.h>
#include <symengine/symengine_casts.h>
namespace SymEngine
{
class Integer : public Number
{
private:
integer_class i;
public:
IMPLEMENT_TYPEID(SYMENGINE_INTEGER)
// explicit Integer(integer_class i);
Integer(const integer_class &_i) : i(_i)
{
SYMENGINE_ASSIGN_TYPEID()
}
Integer(integer_class &&_i) : i(std::move(_i))
{
SYMENGINE_ASSIGN_TYPEID()
}
virtual hash_t __hash__() const;
virtual bool __eq__(const Basic &o) const;
virtual int compare(const Basic &o) const;
signed long int as_int() const;
unsigned long int as_uint() const;
inline const integer_class &as_integer_class() const
{
return this->i;
}
inline virtual bool is_zero() const
{
return this->i == 0u;
}
inline virtual bool is_one() const
{
return this->i == 1u;
}
inline virtual bool is_minus_one() const
{
return this->i == -1;
}
inline virtual bool is_positive() const
{
return this->i > 0u;
}
inline virtual bool is_negative() const
{
return this->i < 0u;
}
// False is returned because a pure integer cannot have an imaginary part
inline virtual bool is_complex() const
{
return false;
}
/* These are very fast methods for add/sub/mul/div/pow on Integers only */
inline RCP<const Integer> addint(const Integer &other) const
{
return make_rcp<const Integer>(this->i + other.i);
}
inline RCP<const Integer> subint(const Integer &other) const
{
return make_rcp<const Integer>(this->i - other.i);
}
inline RCP<const Integer> mulint(const Integer &other) const
{
return make_rcp<const Integer>(this->i * other.i);
}
RCP<const Number> divint(const Integer &other) const;
RCP<const Number> pow_negint(const Integer &other) const;
inline RCP<const Number> powint(const Integer &other) const
{
if (not(mp_fits_ulong_p(other.i))) {
if (other.i > 0u)
throw SymEngineException(
"powint: 'exp' does not fit unsigned long.");
else
return pow_negint(other);
}
integer_class tmp;
mp_pow_ui(tmp, i, mp_get_ui(other.i));
return make_rcp<const Integer>(std::move(tmp));
}
inline RCP<const Integer> neg() const
{
return make_rcp<const Integer>(-i);
}
/* These are general methods, overriden from the Number class, that need to
* check types to decide what operation to do, and so are a bit slower. */
virtual RCP<const Number> add(const Number &other) const
{
if (is_a<Integer>(other)) {
return addint(down_cast<const Integer &>(other));
} else {
return other.add(*this);
}
};
virtual RCP<const Number> sub(const Number &other) const
{
if (is_a<Integer>(other)) {
return subint(down_cast<const Integer &>(other));
} else {
return other.rsub(*this);
}
};
virtual RCP<const Number> rsub(const Number &other) const
{
throw NotImplementedError("Not Implemented");
};
virtual RCP<const Number> mul(const Number &other) const
{
if (is_a<Integer>(other)) {
return mulint(down_cast<const Integer &>(other));
} else {
return other.mul(*this);
}
};
virtual RCP<const Number> div(const Number &other) const
{
if (is_a<Integer>(other)) {
return divint(down_cast<const Integer &>(other));
} else {
return other.rdiv(*this);
}
};
virtual RCP<const Number> rdiv(const Number &other) const;
virtual RCP<const Number> pow(const Number &other) const
{
if (is_a<Integer>(other)) {
return powint(down_cast<const Integer &>(other));
} else {
return other.rpow(*this);
}
};
virtual RCP<const Number> rpow(const Number &other) const
{
throw NotImplementedError("Not Implemented");
};
};
struct RCPIntegerKeyLess {
bool operator()(const RCP<const Integer> &a,
const RCP<const Integer> &b) const
{
return a->as_integer_class() < b->as_integer_class();
}
};
template <typename T>
inline typename std::enable_if<std::is_integral<T>::value,
RCP<const Integer>>::type
integer(T i)
{
return make_rcp<const Integer>(integer_class(i));
}
inline RCP<const Integer> integer(integer_class i)
{
return make_rcp<const Integer>(std::move(i));
}
RCP<const Integer> isqrt(const Integer &n);
int i_nth_root(const Ptr<RCP<const Integer>> &r, const Integer &a,
unsigned long int n);
bool perfect_square(const Integer &n);
bool perfect_power(const Integer &n);
RCP<const Integer> iabs(const Integer &n);
} // SymEngine
#endif