3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-04-07 18:05:21 +00:00
z3/lib/s_integer.h
Leonardo de Moura e9eab22e5c Z3 sources
Signed-off-by: Leonardo de Moura <leonardo@microsoft.com>
2012-10-02 11:35:25 -07:00

150 lines
6 KiB
C++

/*++
Copyright (c) 2006 Microsoft Corporation
Module Name:
integer.h
Abstract:
machine s_integer wrapper
Author:
Leonardo de Moura (leonardo) 2007-06-01.
Revision History:
--*/
#ifndef _S_INTEGER_H_
#define _S_INTEGER_H_
#include"rational.h"
class s_integer {
int m_val;
static s_integer m_zero;
static s_integer m_one;
static s_integer m_minus_one;
public:
unsigned hash() const {
return m_val;
}
struct hash_proc { unsigned operator()(s_integer const& r) const { return r.hash(); } };
struct eq_proc { bool operator()(s_integer const& r1, s_integer const& r2) const { return r1 == r2; } };
void swap(s_integer & n) {
std::swap(m_val, n.m_val);
}
std::string to_string() const;
public:
s_integer(): m_val(0) {}
s_integer(const s_integer & r):m_val(r.m_val) {}
explicit s_integer(int n):m_val(n) {}
struct i64 {};
explicit s_integer(int64 i, i64):m_val(static_cast<int>(i)) {}
struct ui64 {};
explicit s_integer(uint64 i, ui64):m_val(static_cast<int>(i)) {}
explicit s_integer(const char * str);
explicit s_integer(const rational & r):m_val(static_cast<int>(r.get_int64())) {}
void reset() { m_val = 0; }
static bool is_big() { return false; }
static bool is_int() { return true; }
static bool is_s_integer() { return true; }
static bool is_int64() { return true; }
static bool is_uint64() { return true; }
int get_int() const { return m_val; }
int64 get_int64() const { return m_val; }
uint64 get_uint64() const { return m_val; }
static bool is_unsigned() { return true; }
unsigned get_unsigned() const { return static_cast<unsigned>(m_val); }
s_integer const& get_s_integer() const { return *this; }
s_integer const& get_infinitesimal() const { return zero(); }
static bool is_rational() { return true; }
s_integer const& get_rational() const { return *this; }
s_integer & operator=(const s_integer & r) { m_val = r.m_val; return *this; }
friend inline s_integer numerator(const s_integer & r) { return r; }
friend inline s_integer denominator(const s_integer & r) { return one(); }
s_integer & operator+=(const s_integer & r) { m_val += r.m_val; return *this; }
s_integer & operator-=(const s_integer & r) { m_val -= r.m_val; return *this; }
s_integer & operator*=(const s_integer & r) { m_val *= r.m_val; return *this; }
s_integer & operator/=(const s_integer & r) { m_val /= r.m_val; return *this; }
s_integer & operator%=(const s_integer & r) { m_val %= r.m_val; return *this; }
friend inline s_integer div(const s_integer & r1, const s_integer & r2) { return s_integer(r1.m_val / r2.m_val); }
friend inline s_integer mod(const s_integer & r1, const s_integer & r2) {
s_integer r = r1;
r %= r2;
if (r.is_neg()) {
r += r2;
}
return r;
}
s_integer & operator++() { m_val++; return *this; }
const s_integer operator++(int) { s_integer tmp(*this); ++(*this); return tmp; }
s_integer & operator--() { m_val--; return *this; }
const s_integer operator--(int) { s_integer tmp(*this); --(*this); return tmp; }
friend inline bool operator==(const s_integer & r1, const s_integer & r2) { return r1.m_val == r2.m_val; }
friend inline bool operator<(const s_integer & r1, const s_integer & r2) { return r1.m_val < r2.m_val; }
void neg() { m_val = -m_val; }
bool is_zero() const { return m_val == 0; }
bool is_one() const { return m_val == 1; }
bool is_minus_one() const { return m_val == -1; }
bool is_neg() const { return m_val < 0; }
bool is_pos() const { return m_val > 0; }
bool is_nonneg() const {return m_val >= 0; }
bool is_nonpos() const { return m_val <= 0; }
bool is_even() const { return (!(m_val & 0x1)); }
friend inline s_integer floor(const s_integer & r) { return r; }
friend inline s_integer ceil(const s_integer & r) { return r; }
s_integer expt(int n) const {
s_integer result(1);
for (int i = 0; i < n; i++) {
result *= *this;
}
return result;
}
static const s_integer & zero() { return m_zero; }
static const s_integer & one() { return m_one; }
static const s_integer & minus_one() { return m_minus_one; }
// Perform: this += c * k
void addmul(const s_integer & c, const s_integer & k) { m_val += c.m_val * k.m_val; }
void submul(const s_integer & c, const s_integer & k) { m_val -= c.m_val * k.m_val; }
friend inline std::ostream & operator<<(std::ostream & target, const s_integer & r) {
target << r.m_val;
return target;
}
rational to_rational() const { return rational(m_val); }
};
inline bool operator!=(const s_integer & r1, const s_integer & r2) { return !operator==(r1, r2); }
inline bool operator>(const s_integer & r1, const s_integer & r2) { return operator<(r2, r1); }
inline bool operator<=(const s_integer & r1, const s_integer & r2) { return !operator>(r1, r2); }
inline bool operator>=(const s_integer & r1, const s_integer & r2) { return !operator<(r1, r2); }
inline s_integer operator+(const s_integer & r1, const s_integer & r2) { return s_integer(r1) += r2; }
inline s_integer operator-(const s_integer & r1, const s_integer & r2) { return s_integer(r1) -= r2; }
inline s_integer operator-(const s_integer & r) { s_integer result(r); result.neg(); return result; }
inline s_integer operator*(const s_integer & r1, const s_integer & r2) { return s_integer(r1) *= r2; }
inline s_integer operator/(const s_integer & r1, const s_integer & r2) { return s_integer(r1) /= r2; }
inline s_integer operator%(const s_integer & r1, const s_integer & r2) { return s_integer(r1) %= r2; }
s_integer power(const s_integer & r, unsigned p);
s_integer gcd(const s_integer & r1, const s_integer & r2);
s_integer lcm(const s_integer & r1, const s_integer & r2);
inline s_integer abs(const s_integer & r) {
s_integer result(r);
if (result.is_neg()) {
result.neg();
}
return result;
}
#endif /* _S_INTEGER_H_ */